#!/usr/bin/newlisp # # Brainf*ck interpreter - requires newlisp 8.7.0 or newer # # Read all about Brainf*ck in Wikipedia: # http://en.wikipedia.org/wiki/Brainfuck # # Version 1.0 # - Initial release # # Version 1.1 # - Nested jumps work now, all BF programs run correctly # - Speed optimizations # # Version 1.2 # - Code optimizations # # Usage: bf.lsp # # Dec 11, 2004 / Nov 5, 2005 - PvE # #-------------------------------------------------------- # Define global constants (constant 'memsize 30000) (constant 'celsize 255) # Set memory to 0 as list (set 'memory (dup 0 memsize)) # Set The Pointer position at 0 (set 'pointer 0) # Set current position in program to 0 (set 'interpret 0) (set 'jumppos 0) # Read the program (if (= (nth 1 (main-args)) (nth 2 (main-args))) (begin (println "Usage: ./bf.lsp ") (exit))) (set 'program (read-file (nth 2 (main-args)))) (if (= (length program) 0) (begin (println "Could not open program!") (exit))) # Analyze jumps - create list (while (< jumppos (length program)) (if (= (nth jumppos program) "[") (begin (push jumppos jumplist) (set 'bo 0) (do-until (or (= jumppos (length program)) (= bo -1)) (inc 'jumppos) (if (= (nth jumppos program) "[") (inc 'bo)) (if (= (nth jumppos program) "]") (dec 'bo)) (if (= bo -1) (push jumppos jumplist))) (if (!= bo -1) (begin (println "No matching ] found for [ at " (string (first jumplist))) (exit))) (set 'jumppos (nth 1 jumplist)))) (inc 'jumppos)) # Parse main loop (while (< interpret (length program)) # Read character (case (nth interpret program) # Increase position of The Pointer (">" (inc 'pointer)) # Decrease position of The Pointer ("<" (dec 'pointer)) # Increase value in current mem address ("+" (nth-set pointer memory (& (+ (nth pointer memory) 1) celsize))) # Decrease value in current mem address ("-" (nth-set pointer memory (& (- (nth pointer memory) 1) celsize))) # Print 1 char at The Pointer to STDOUT ("." (print (char (nth pointer memory)))) # Get 1 char and store it at The Pointer ("," (nth-set pointer memory (read-key))) # Move the interpreter position forward ("[" (if (= (nth pointer memory) 0) (set 'interpret (nth (- (find interpret jumplist) 1) jumplist)))) # Move the interpreter position backward ("]" (if (!= (nth pointer memory) 0) (set 'interpret (nth (+ (find interpret jumplist) 1) jumplist)))) # Debug command ("#" (for (y 0 9) (println) (for (x 0 9) (print (string (nth (+ (* y 10) x) memory)) " "))) (println "\nPosition of pointer: " (string pointer)))) # Next position (inc 'interpret)) # Exit newLisp (exit)