### newLISP: Hello World Example Source: https://github.com/kosh04/newlisp/blob/develop/newlisp-js/simple.html A basic newLISP example demonstrating printing 'Hello World' and defining/calling a simple function `double`. ```newlisp ; Welcome to newLISP running in a browser. ; based on newLISP v10.7.5 (2019), Emscripten v1.38.12 ; best used with Firefox browser ; Click [eval] (println "Hello World") (define (double x) (+ x x)) (println "=> " (double 123)) ; [eval] shows all the return values from ; evaluated expressions plus the effect from ; 'println'. Now click [silent]. It only shows ; the effect from the 'println' expression. ; To find out more about how to use this ; editor, click the [info] button. ; The best introduction to newLISP can be found ; here: ; en.wikibooks.org/wiki/Introduction_to_newLISP ; ; More documentation can be found here: ; www.newlisp.org/index.cgi?Documentation ; or by clicking the [doc] button. ``` -------------------------------- ### Start newLISP Server (Basic) Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Starts the newLISP server with specified thread timeout and data directory. This is a basic server startup without explicit HTTP or logging configurations. ```shell newlisp -c -t 3000000 -d 4711 & ``` -------------------------------- ### newLISP Basic Examples Source: https://github.com/kosh04/newlisp/blob/develop/newlisp-js/newlisp-js.html Demonstrates basic newLISP syntax for printing output, defining functions, and performing arithmetic operations within the browser environment. ```newlisp ; Welcome to newLISP running in a browser. ; based on newLISP v10.7.5 (2019), Emscripten v1.38.12 ; best used with Firefox browser (println "Hello World") (define (double x) (+ x x)) (println "=> " (double 123)) ``` -------------------------------- ### newLISP Example Function 'foo' Source: https://github.com/kosh04/newlisp/blob/develop/doc/newLISPdoc.html This snippet demonstrates a documented newLISP function 'foo' using the newLISPdoc tagging system. It shows how to define a module, author, version, parameters, and provide a code example with expected output. ```newLISP ;; @module example.lsp ;; @author John Doe, johndoe@example.com ;; @version 1.0 ;; ;; This module is an example module for the newlispdoc ;; program, which generates automatic newLISP module ;; documentation. ;; @syntax (example:foo ) ;; @param The number of times to repeat. ;; @param The message string to be printed. ;; @return Returns the message in ;; ;; The function 'foo' repeatedly prints a string to ;; standard out terminated by a line feed. ;; ;; @example ;; (example:foo 5 "hello world") ;; => ;; "hello world" ;; "hello world" ;; "hello world" ;; "hello world" ;; "hello world" ;; (context 'example) (define (foo n msg) (dotimes (i n) (println msg)) ) ``` -------------------------------- ### Start newLISP HTTP Server with Web Root Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Starts the newLISP server for HTTP requests, defining the startup and web root directory. The server listens on port 8080 and runs in the background. ```shell newlisp -http -d 8080 -w /usr/home/www/httpdocs & ``` -------------------------------- ### Executing Specific Newlisp Test Files Source: https://github.com/kosh04/newlisp/blob/develop/qa-specific-tests/HOWTOTEST.txt You can execute individual Newlisp test files directly from the command line. This is useful for targeted testing or debugging specific functionalities. The example shows running a 'qa-net6' test file. ```bash ./newlisp qa-specific-tests/qa-net6 ``` -------------------------------- ### newlisp Usage Examples Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Demonstrates common ways to invoke the newLISP interpreter for interactive sessions, executing scripts, evaluating expressions remotely, and running as a network server. ```newlisp Start interactive session newlisp ``` ```newlisp Excute a program newlisp myprog.lsp ``` ```newlisp Excute a remote program newlisp http://newlisp.org/example.lsp ``` ```newlisp Add 3 and 4, 7 prints on standard output newlisp -e "(+ 3 4)" ``` ```newlisp newLISP is started as a server (the & indicates to LINUX to run the process in the background) and can be connected to with telnet by issu- img telnet localhost 1234 newlisp -p 1234 & ``` ```newlisp newLISP is started as a server for another newlisp process connecting with the net-eval function or HTTP requests. Connection timeout is 3 seconds. newlisp -p 1234 -t 3000 & ``` -------------------------------- ### Start newLISP HTTP Server with Configuration File Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Starts the newLISP server for HTTP requests, loading a configuration file (httpd.conf) to preprocess request paths. It specifies the web root and runs on port 8080. ```shell newlisp httpd.conf -http -d 8080 -w /usr/home/www/httpdocs & ``` -------------------------------- ### Start newLISP HTTP Server with Logging Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Starts the newLISP server to handle HTTP requests and logs connections to a specified file. The server is configured to run in the background. ```shell newlisp -l /usr/home/www/log.txt -http -d 8080 & ``` -------------------------------- ### newLISP Message Evaluation and Proxy Example Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates inter-process communication and message evaluation in newLISP using `spawn`, `send`, `receive`, and `eval`. It shows how one process can act as a proxy to evaluate messages sent by another, facilitating dynamic control flow and data exchange. Key functions include `spawn` for creating processes, `sys-info` to get parent PID, `send` to transmit messages, `receive` to get messages, and `eval` to execute expressions within a message. ```newLISP #!/usr/bin/newlisp ; sender child process of the message (set 'A (spawn 'result (begin (dotimes (i 3) (set 'ppid (sys-info -4)) /\* the following statement in msg will be evaluated in the proxy \*/ (set 'msg '(until (send B (string "greetings from " A)))) (until (send ppid msg))) (until (send ppid '(begin (sleep 200) ; make sure all else is printed (println "parent exiting ...\n") (set 'finished true))))) true)) ; receiver child process of the message (set 'B (spawn 'result (begin (set 'ppid (sys-info -4)) (while true (until (receive ppid msg)) (println msg) (unless (= msg (string "greetings from " A)) (println "ERROR in proxy message: " msg)))) true)) (until finished (if (receive A msg) (eval msg))) ; proxy loop (abort) (exit) ``` -------------------------------- ### Create C Wrapper for newLISP Library Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates creating a C wrapper library (`wrapper.c`) to bridge calling conventions between newLISP and external libraries. Includes compilation instructions for shared libraries and usage examples from newLISP. ```bash gcc -m32 -shared wrapper.c -o wrapper.so or: gcc -m32 -bundle wrapper.c -o wrapper.dylib ``` ```newLISP (import "./wrapper.dylib" "wrapperFoo") (define (glFoo x y z) (get-float (wrapperFoo 5 (float x) (int y) (float z))) ) (glFoo 1.2 3 1.4) => 7.8 ``` ```C #include #include /* the glFoo() function would normally live in the library to be wrapped, e.g. libopengl.so or libopengl.dylib, and this program would link to it. For demo and test purpose the function has been included in this file */ double glFoo(double x, int y, double z) { double result; result = (x + z) * y; return(result); } /* this is the wrapper for glFoo which gets imported by newLISP declaring it as a va-arg function guarantees 'cdecl' calling conventions on most architectures */ double * wrapperFoo(int argc, ...) { va_list ap; double x, z; static double result; int y; va_start(ap, argc); x = va_arg(ap, double); y = va_arg(ap, int); z = va_arg(ap, double); va_end(ap); result = glFoo(x, y, z); return(&result); } /* eof */ ``` -------------------------------- ### Sample URL File Content Source: https://github.com/kosh04/newlisp/blob/develop/doc/newLISPdoc.html Provides an example of the content expected in a URL file used with the '-url' flag. Each line in this file should contain a single URL pointing to a newLISP source file. ```text http://asite.com/code/afile.lsp http://othersite.org/somefile.lsp file:///usr/home/joe/program.lsp ``` -------------------------------- ### newLISP GLUT Initialization and Main Loop Source: https://github.com/kosh04/newlisp/blob/develop/examples/opengl-demo-ffi-lsp.txt Initializes GLUT, sets window properties (size, position, display mode), registers callback functions for various events, and starts the main event processing loop. ```newLISP (set 'argc 0) (set 'argv1 "") (set 'argv (pack "lu" argv1)) (set 'rotx 0.0) (set 'roty 0.0) (set 'PI (mul (acos 0) 2)) (glutInit (address argc) (address argv)) (glutInitDisplayMode (| GLUT_RGB GLUT_DOUBLE )) (glutInitWindowSize 800 600) (glutInitWindowPosition 80 80) (set 'id (glutCreateWindow "OpenGL and newLISP - drag mouse - ESC to exit")) (glClearColor 0.5 0.3 0.3 0.0) (glColor3d 1.0 0.85 0.35) (glutDisplayFunc (callback 'draw "void")) ;(glutDisplayFunc (callback 0 'drawObject)) (glutKeyboardFunc (callback 'keyboard "void" "byte" "int" "int")) (glutMouseFunc (callback 'mouse "void" "int" "int" "int" "int")) (glutMotionFunc (callback 'motion "void" "int" "int")) (glutIdleFunc (callback 'rotation "void")) (glutJoystickFunc (callback 'joystick "void" "int" "int" "int" "int") 50) (glutMainLoop) ;; eof ;(glEnable GL_BLEND) ;(glEnable GL_LINE_SMOOTH) ; turn on antialiasing ;(glHint GL_LINE_SMOOTH_HINT GL_DONT_CARE) ;(glLineWidth 3) ``` -------------------------------- ### newLISP Shebang and Command Line Options Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates how to use the newLISP interpreter as a shebang in scripts and configure command-line options like stack size (-s) and memory limits (-m). Includes examples of accessing script arguments and system information. ```newLISP #!/usr/bin/newlisp (println (main-args)) (println (sys-info)) (exit) ; important ``` ```newLISP #!/usr/bin/newlisp -s 100000 ; Script with increased stack size ``` ```newLISP #!/usr/bin/newlisp -s100000 ; Script with attached stack size parameter ``` ```newLISP #!/usr/bin/newlisp -s 100000 -m 10 ; Script with increased stack and memory limits ``` -------------------------------- ### Test newLISP Server with Telnet Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates how to connect to a running newLISP server using the telnet utility. This is useful for interactive testing and sending commands to the server. Examples are provided for connecting to a local server and a remote server via IP address. ```shell telnet localhost 4711 ``` ```shell telnet 192.168.1.100 4711 ``` -------------------------------- ### Newlisp Test Suite Execution with Make Source: https://github.com/kosh04/newlisp/blob/develop/qa-specific-tests/HOWTOTEST.txt These commands utilize the 'make' utility to run Newlisp's test suites. They offer options for short or long test suites and different reporting verbosity levels. 'make test' and 'make testall' are common targets. ```make make test # For a short suite and less reporting make check # For a short suite with full reporting make testall # For a long suite with less reporting make checkall # For a long suite with full reporting make clean; make; make testall # Common sequence for building and testing ``` -------------------------------- ### Run Android Emulator Source: https://github.com/kosh04/newlisp/blob/develop/doc/ANDROID.txt Starts the Android emulator for the AVD named 'MyEmulator'. The emulator provides a virtual environment to run and test Android applications. ```shell kanen (~/Code/android-sdk/tools)$ ./emulator -avd MyEmulator ``` -------------------------------- ### Generate Newlisp HTML Documentation Source: https://github.com/kosh04/newlisp/blob/develop/modules/README.txt Execute the `newlispdoc` utility to generate HTML documentation for Newlisp modules. This command processes all `.lsp` files in the current directory, creating an `index.html` and individual HTML files for each module. Refer to `newLISPdoc.html` for additional conversion options. ```newlisp newlispdoc -s -d *.lsp ``` ```newlisp newlisp newlispdoc -s -d *.lsp ``` -------------------------------- ### Evaluate newLISP Code from C using dlopen Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Provides a C program example that dynamically loads the newLISP shared library (`.so`) using `dlopen` and `dlsym`. It shows how to obtain a function pointer to `newlispEvalStr` and execute newLISP expressions passed as command-line arguments, printing the evaluated results. ```C /* libdemo.c - demo for importing newlisp.so * * compile using: * gcc -ldl libdemo.c -o libdemo * * use: * * ./libdemo '(+ 3 4)' * ./libdemo '(symbols)' * */ #include #include int main(int argc, char * argv[]) { void * hLibrary; char * result; char * (*func)(char *); char * error; if((hLibrary = dlopen("/usr/lib/newlisp.so", RTLD_GLOBAL | RTLD_LAZY)) == 0) { printf("cannot import library\n"); exit(-1); } func = dlsym(hLibrary, "newlispEvalStr"); if((error = dlerror()) != NULL) { printf("error: %s\n", error); exit(-1); } printf("%s\n", (*func)(argv[1])); return(0); } /* eof */ ``` -------------------------------- ### newLISP net-eval for Distributed Computation Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates setting up node parameters and executing code remotely using newLISP's `net-eval`. It shows how to distribute tasks across multiple nodes and aggregate results, including an example with a callback routine. ```newLISP #!/usr/bin/newlisp ; node parameters (set 'nodes '( ("192.168.1.100" 4711) ("192.168.1.101" 4711) ("192.168.1.102" 4711) ("192.168.1.103" 4711) ("192.168.1.104" 4711) )) ; program template for nodes (set 'program "\ (begin (map set '(from to node) '(%d %d %d)) (for (x from to) (if (= 1 (length (factor x))) (push x primes -1))) primes) ") ; call back routine for net-eval (define (idle-loop p) (when p (println (p 0) ":" (p 1)) (push (p 2) primes)) ) (println "Sending request to nodes, and waiting ...") ; machines could be on different IP addresses. ; For this test 5 nodes are started on localhost (set 'result (net-eval (list (list (nodes 0 0) (nodes 0 1) (format program 0 99999 1)) (list (nodes 1 0) (nodes 1 1) (format program 100000 199999 2)) (list (nodes 2 0) (nodes 2 1) (format program 200000 299999 3)) (list (nodes 3 0) (nodes 3 1) (format program 300000 399999 4)) (list (nodes 4 0) (nodes 4 1) (format program 400000 499999 5)) ) 20000 idle-loop)) (set 'primes (sort (flat primes))) (save "primes" 'primes) (exit) ``` ```newLISP ; Alternative scheme without idle-loop (set 'node-eval-list (list (list (nodes 0 0) (nodes 0 1) (format program 0 99999 1)) (list (nodes 1 0) (nodes 1 1) (format program 100000 199999 2)) (list (nodes 2 0) (nodes 2 1) (format program 200000 299999 3)) (list (nodes 3 0) (nodes 3 1) (format program 300000 399999 4)) (list (nodes 4 0) (nodes 4 1) (format program 400000 499999 5)) )) (set 'result (net-eval node-eval-list 20000)) ``` -------------------------------- ### Producer-Consumer with Semaphores and Shared Memory Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html A comprehensive example illustrating the producer-consumer pattern using newLISP's process management, semaphores for synchronization, and shared memory for data exchange. It includes definitions for consumer, producer, and a run function to manage processes and semaphores. ```newlisp #!/usr/bin/newlisp # prodcons.lsp - Producer/consumer # # usage of 'fork', 'wait-pid', 'semaphore' and 'share' (when (= ostype "Win32") (println "this will not run on Win32") (exit)) (constant 'wait -1 'sig 1 'release 0) (define (consumer n) (set 'i 0) (while (< i n) (semaphore cons-sem wait) (println (set 'i (share data)) " <-") (semaphore prod-sem sig)) (exit)) (define (producer n) (for (i 1 n) (semaphore prod-sem wait) (println ">-> " (share data i)) semaphore cons-sem sig)) (exit)) (define (run n) (set 'data (share)) (share data 0) (set 'prod-sem (semaphore)) ; get semaphores (set 'cons-sem (semaphore)) (set 'prod-pid (fork (producer n))) ; start processes (set 'cons-pid (fork (consumer n))) (semaphore prod-sem sig) ; get producer started (wait-pid prod-pid) ; wait for processes to finish (wait-pid cons-pid) ; (semaphore cons-sem release) ; release semaphores (semaphore prod-sem release)) (run 10) (exit) ``` -------------------------------- ### Register newLISP Callback Function Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates registering a callback function in newLISP. It imports `newlispEvalStr` and `newlispCallback`, defines a `callme` function, and registers it. The example shows invoking the callback with different return types (string and number) and printing the results. ```newlisp #!/usr/bin/newlisp ; path-name of the library depending on platform (set 'LIBRARY (if (= ostype "Win32") "newlisp.dll" "newlisp.dylib")) ; import functions from the newLISP shared library (import LIBRARY "newlispEvalStr") (import LIBRARY "newlispCallback") ; set calltype platform specific (set 'CALLTYPE (if (= ostype "Win32") "stdcall" "cdecl")) ; the callback function (define (callme p1 p2 p3 result) (println "p1 => " p1 " p2 => " p2 " p3 => " p3) result) ; register the callback with newLISP library (newlispCallback "callme" (callback 0 'callme) CALLTYPE) ; the callback returns a string (println (get-string (newlispEvalStr {(get-string (callme 123 456 789 "hello world"))}))) ; the callback returns a number (println (get-string (newlispEvalStr {(callme 123 456 789 99999)}))) ``` -------------------------------- ### Emscripten Newlisp Setup and Evaluation Source: https://github.com/kosh04/newlisp/blob/develop/newlisp-js/newlisp-js.html This JavaScript code configures the Emscripten environment for Newlisp. It defines how to evaluate Newlisp code from a textarea element, handles output redirection to a log function, and manages status messages and progress updates for the Emscripten module. It also includes logic for initializing UI elements and event listeners after the module is ready. ```javascript var Module = { preRun: [], postRun: [ (function() { newlispEvalStr = Module.cwrap('newlispEvalStr', 'string', ['string']); // preload newLISP functions from code textarea id='code' newlispEvalStr(document.getElementById('code').value); }) ], print: (function() { // var element = document.getElementById('output'); // element.value = ''; // clear browser cache return function(text) { text = Array.prototype.slice.call(arguments).join(' '); writeLog(text); // element.value += text + "\n"; // element.scrollTop = 99999; // focus on bottom }; })(), printErr: function(text) { text = Array.prototype.slice.call(arguments).join(' '); console.log(text); }, canvas: document.getElementById('canvas'), setStatus: function(text) { if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; if (text === Module.setStatus.text) return; var m = text.match(/([^\s]+\s+\([^\)]+\)\s+)([0-9]+(?:\.[0-9]+)?)\/([0-9]+)/); var now = Date.now(); if (m && now - Module.setStatus.last.time < 30) { // if progress update, skip it if too soon return; } var statusElement = document.getElementById('status'); var progressElement = document.getElementById('progress'); if (m) { text = m[1]; progressElement.value = parseInt(m[2]) * 100; progressElement.max = parseInt(m[4]) * 100; progressElement.hidden = false; } else { progressElement.value = null; progressElement.max = null; progressElement.hidden = true; // start application, start CodeMirror, restore local storage and layout if (editor == false) { enableButtons(); initCoderMirrorWidgets(); restoreLocalStorage(); restoreLayoutAndTheme(); window.onresize = resizeTextarea; //file browser document.getElementById('files').addEventListener('change', handleFileSelect, false); } if (isMobile.any()) { // settings for mobile device orientation discovery window.onorientationchange = detectIPadOrientation; // on mobile scroll page into position when keyboard closes document.addEventListener('focusout', function(e) { window.scrollTo(0, 0); }); } } statusElement.innerHTML = text; }, totalDependencies: 0, monitorRunDependencies: function(left) { this.totalDependencies = Math.max(this.totalDependencies, left); Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies - left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); } }; Module.setStatus('Downloading...'); ``` -------------------------------- ### Emscripten Setup for newLISP Evaluation Source: https://github.com/kosh04/newlisp/blob/develop/newlisp-js/simple.html This JavaScript code configures Emscripten to load the newLISP library. It defines functions for evaluating newLISP code strings, handling console output, and updating the UI with download/execution status. It wraps the 'newlispEvalStr' function from the Emscripten module and sets up event listeners for file selection and window resizing. ```javascript var Module = { preRun: [], postRun: [ function() { newlispEvalStr = Module.cwrap('newlispEvalStr', 'string', ['string']); // preload newLISP functions from code textarea id='code' newlispEvalStr(document.getElementById('code').value); } ], print: (function() { var element = document.getElementById('output'); element.value = ''; // clear browser cache return function(text) { text = Array.prototype.slice.call(arguments).join(' '); element.value += text + "\n"; element.scrollTop = 99999; // focus on bottom }; })(), printErr: function(text) { text = Array.prototype.slice.call(arguments).join(' '); console.log(text); }, setStatus: function(text) { if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; if (text === Module.setStatus.text) return; var m = text.match(/([^()]+)\/(\d+(\.\d+)?)\/(\d+)/); var now = Date.now(); if (m && now - Date.now() < 30) return; // if progress update, skip it if too soon var statusElement = document.getElementById('status'); var progressElement = document.getElementById('progress'); if (m) { text = m[1]; progressElement.value = parseInt(m[2]) * 100; progressElement.max = parseInt(m[4]) * 100; progressElement.hidden = false; } else { progressElement.value = null; progressElement.max = null; progressElement.hidden = true; // leave file selection button disabled on Android, IOS and mobile Windows if (isMobile.any()) { document.getElementById('files').disabled = true; document.getElementById('browse').disabled = true; } document.getElementById('files').addEventListener('change', handleFileSelect, false); // restore editor layout settings restoreLayoutAndTheme(); window.onresize = resizeTextarea; editorSetFocus(); if (isMobile.any()) { // settings for mobile discover orientation window.onorientationchange = detectIPadOrientation; // on mobile scroll page into position when keyboard closes document.addEventListener('focusout', function(e) { window.scrollTo(0, 0); }); } // EMSCRIPTEN finish download status update code } statusElement.innerHTML = text; }, totalDependencies: 0, monitorRunDependencies: function(left) { this.totalDependencies = Math.max(this.totalDependencies, left); Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies - left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); } }; Module.setStatus('Downloading...'); ``` -------------------------------- ### Test newLISP Server with Netcat Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Shows how to use the netcat (nc) utility to send commands to the newLISP server. This method is effective for scripting simple interactions and testing server responses. It includes examples for both local and remote connections, sending a '(symbols) (exit)' command. ```shell echo '(symbols) (exit)' | nc localhost 4711 ``` ```shell echo '(symbols) (exit)' | nc 192.168.1.100 4711 ``` -------------------------------- ### Parallel Prime Calculation using Cilk API (spawn/sync) Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates parallel processing by distributing the task of finding prime numbers across multiple child processes using newLISP's Cilk API ('spawn' and 'sync'). It includes examples of waiting for processes and handling timeouts. ```newlisp ; calculate primes in a range (define (primes from to) (let (plist '()) (for (i from to) (if (= 1 (length (factor i))) (push i plist -1))) plist)) ; start child processes (set 'start (time-of-day)) (spawn 'p1 (primes 1 1000000)) (spawn 'p2 (primes 1000001 2000000)) (spawn 'p3 (primes 2000001 3000000)) (spawn 'p4 (primes 3000001 4000000)) ; wait for a maximum of 60 seconds for all tasks to finish (sync 60000) ; returns true if all finished in time ; p1, p2, p3 and p4 now each contain a lists of primes ; print a dot after each 2 seconds of waiting (until (sync 2000) (println ".")) ; show a list of pending process ids after ;each three-tenths of a second (until (sync 300) (println (sync))) ``` -------------------------------- ### newLISP CGI Redirect Example Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html An example of a newLISP CGI script that performs an HTTP redirect. It customizes the HTTP status header to '301 Moved Permanently' and specifies a new 'Location' for the client. ```newlisp #!/usr/bin/newlisp (print "Status: 301 Moved Permanently\r\n") (print "Location: http://www.newlisp.org/index.cgi\r\n\r\n") (exit) ``` -------------------------------- ### NewLISP Blocking Parent-Child Message Exchange Example Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html A comprehensive example showing a parent process spawning multiple child processes. Children send random numbers to the parent, which uses blocking 'receive' to collect and display messages from each child. The 'sync' function retrieves active child PIDs. ```newlisp #!/usr/bin/newlisp ; child process transmits random numbers (define (child-process) (set 'ppid (sys-info -4)) ; get parent pid (while true (until (send ppid (rand 100)))) ) ; parent starts 5 child processes, listens and displays ; the true flag enables usage of send and receive (dotimes (i 5) (spawn 'result (child-process) true)) (for (i 1 3) (dolist (cpid (sync)) ; iterate thru pending child PIDs (until (receive cpid msg)) (print "pid:" cpid "->>" (format "%\-2d " msg))) (println) ) (abort) ; cancel child-processes (exit) ``` -------------------------------- ### newlisp Command-Line Interface Source: https://github.com/kosh04/newlisp/blob/develop/doc/newlisp-man.txt Describes the syntax for invoking the newLISP interpreter and its various command-line options. This includes parameters for initialization, linking, help, version display, prompt control, HTTP mode, stack and memory limits, file execution, program evaluation, startup directory, logging, network listening, demon mode, connection timeouts, and IPv6 support. ```APIDOC newlisp(1) Commandline Parameters newlisp(1) NAME newlisp - lisp like programming language SYNOPSIS newlisp [-n] [-x source target] [-h | -v] [-c | -C | -http] [-t microseconds] [-s stack] [-m max-mem-megabyte] [[-l path-file | -L path-file] [-p port-number | -d port-number]] [-w directory] [lisp-files ...] [-e programtext] DESCRIPTION Invokes newLISP which first loads init.lsp if present. Then one or more options and one or more newLISP source files can be specified. The options and source files are executed in the sequence they appear. For some options is makes sense to have source files loaded first like for the -p and -d options. For other options like -s and -m it is logical to specify these before the source files to be loaded. If a -e switch is used the programtext is evaluated and then newlisp exits otherwise evaluation continues interactively (unless an exit occurs during lisp-file interpretation). OPTIONS -n Suppress loading of any init.lsp or .init.lsp initialization file. -x source target Link the newLISP executable with a source file to built a new target executable. -h Display a short help text. -v Display a version string. -c Suppress the commandline prompt. -C Force prompt when running newLISP in pipe I/O mode for Emacs. -http only accept HTTP commands -s stacksize Stack size to use when starting newLISP. When no stack size is specified the stack defaults to 1024. -m max-mem-megabyte Limits memory to max-cell-mem-megabyte megabytes for Lisp cell memory. lisp-files Load and evaluate the specified lisp source files in sequence. Source files can be specified using URLs. If an (exit) is exe- cuted by one of the source files then newlisp exits and all pro- cessing ceases. -e programtext Programtext is an expression enclosed in quotation marks which is evaluated and the result printed to standard out device (STD- OUT). In most UNIX system shells apostrophes can also be used to delimit the expression. newLISP exits after evaluation of pro- gramtext is complete. -w directory Directory is the start up directory for newLISP. Any file refer- ence in a program will refer to this directory by default as the current directory. This can be used to define a web root direc- tory when in server mode. -l -L path-file Log network connections and newLISP I/O to the file in path-file. -l will only log network connections or commandline input or net-eval requests. -L will additionally log HTTP requests and newLISP output from commandline and net-eval input. -p port-number Listen for commands on a TCP/IP socket connection. In this case standard I/O is redirected to the port specified in the -p option. Any specified lisp-files will be loaded the first time a connection is made, that is, before text is accepted from the port connection. -d port-number Run in demon mode. As for the -p option, but newLISP does not exit after a closed connection and stays in memory listening for a new connection. -t microseconds-connection-timeout Specifies a connection timeout when running in -p or -d demon mode. Server will disconnect when no further input is read after accepting a client connection. -6 Starts newLISP in IPv6 'Internet Protocol version 6' mode. With- out this switch newLISP willl start in IPv4 mode. The protocol mode can also be switched with the built-in 'net-ipv' function during runtime. ``` -------------------------------- ### JavaScript: Caret Position Utilities Source: https://github.com/kosh04/newlisp/blob/develop/newlisp-js/simple.html Provides functions to get and set the cursor (caret) position within a text input element, supporting different browser implementations. ```javascript function getCaretPosition (field) { var caretPos = 0; // IE 9 and after if (document.selection) { field.focus (); var sel = document.selection.createRange (); sel.moveStart ('character', - field.value.length); caretPos = sel.text.length; } // Firefox, Safari, Chrome else if (field.selectionStart || field.selectionStart == '0') { caretPos = field.selectionStart; } return (caretPos); } function setCaretPosition(elem, caretPos) { if(elem !== null) { // IE 6 and after if(elem.createTextRange) { var range = elem.createTextRange(); range.move('character', caretPos); range.select(); } // Firefox, Safari, Chrome else { if(elem.selectionStart) { elem.focus(); elem.setSelectionRange(caretPos, caretPos); } else elem.focus(); } } } ``` -------------------------------- ### Module System: Multiple Contexts and Switching Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Explains how to manage multiple contexts within a single file and how to switch between them. It covers explicit context closing with `(context MAIN)` and the more concise method of switching and opening new contexts using qualified names like `(context 'MAIN:B)`. ```newLISP ; myapp.lsp ; (context 'A) (define (foo ...) ...) (context MAIN) (context 'B) (define (bar ...) ...) (context MAIN) (define (main-func) (A:foo ...) (B:bar ...) ) ``` ```newLISP ; myapp.lsp (alternative switching) ; (context 'A) (define (foo ...) ...) (context 'MAIN:B) (define (bar ...) ...) (context 'MAIN) (define (main-func) (A:foo ...) (B:bar ...) ) ``` -------------------------------- ### Register Callbacks in newLISP Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates how to register callback functions in external libraries using newLISP's `callback` function. This allows external libraries to call back into the newLISP program, for example, for event handling. ```newLISP (define (keyboard key x y) (if (= (& key 0xFF) 27) (exit)) ; exit program with ESC (println "key:" (& key 0xFF) " x:" x " y:" y)) (glutKeyboardFunc (callback 1 'keyboard)) ``` -------------------------------- ### Importing C Libraries with Different Calling Conventions Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Shows how to import functions from a C library into newLISP. It includes an example of specifying the 'cdecl' calling convention for libraries compiled with it, which differs from the default stdcall convention. ```newLISP ; import a library compiled for cdecl ; calling conventions (import "foo.dll" "func" "cdecl") ``` -------------------------------- ### Expand from Uppercase Variables in newLISP Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Shows how 'expand' automatically targets variables starting with an uppercase letter for expansion when no explicit symbols or association lists are provided. This offers a convenient shorthand for common expansion scenarios. ```newLISP ; expand from uppercase variables (set 'A 1 'Bvar 2 'C nil 'd 5 'e 6) (expand '(A (Bvar) C d e f)) → (1 (2) C d e f) ``` ```newLISP ; use expansion from uppercase variables in function factories (define (raise-to Power) (expand (fn (base) (pow base Power)))) (define cube (raise-to 3)) → (lambda (base) (pow base 3)) (cube 4) → 64 ``` -------------------------------- ### Basic newLISPdoc Usage Source: https://github.com/kosh04/newlisp/blob/develop/doc/newLISPdoc.html Demonstrates the fundamental command to process newLISP source files and generate HTML documentation. This command processes specified .lsp files and creates corresponding HTML files along with an index.html. ```shell newLISPdoc mysql.lsp odbc.lsp sqlite.lsp ``` -------------------------------- ### newLISP Script as a Pipe Filter (Uppercase) Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html An example of a newLISP script designed to be used as a pipe filter. It reads lines from standard input, converts them to uppercase using the `upper-case` function, and writes the result to standard output. ```newLISP #!/usr/bin/newlisp # # uppercase - demo filter script as pipe # # usage: # ./uppercase < file-spec # # example: # ./uppercase < my-text # (while (read-line) (println (upper-case (current-line)))) (exit) ``` -------------------------------- ### Nested Function Modification Example Source: https://github.com/kosh04/newlisp/blob/develop/doc/CodePatterns.html Demonstrates how Newlisp's behavior of returning references to list elements can be leveraged for nested function calls, specifically showing how sorting a list and then popping an element modifies the original list. ```newlisp (set 'L '(r w j s r b)) ; Sort L and then pop the first element (which is the smallest after sorting) (pop (sort L)) ; → b ; L → (j r r s w) ```