Fixed the bug in PROG!
This commit is contained in:
		
							parent
							
								
									33079232e1
								
							
						
					
					
						commit
						dc46735f55
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -21,3 +21,5 @@ Sysout*.lsp | ||||||
| *.pdf | *.pdf | ||||||
| 
 | 
 | ||||||
| src/beowulf/scratch.clj | src/beowulf/scratch.clj | ||||||
|  | 
 | ||||||
|  | .portal/vs-code.edn | ||||||
|  |  | ||||||
|  | @ -77,7 +77,7 @@ You are of course welcome to fork the project and do whatever you like with it! | ||||||
| 
 | 
 | ||||||
| Invoke with | Invoke with | ||||||
| 
 | 
 | ||||||
|     java -jar target/uberjar/beowulf-0.3.0-standalone.jar --help |     java -jar target/uberjar/beowulf-0.3.1-standalone.jar --help | ||||||
| 
 | 
 | ||||||
| (Obviously, check your version number) | (Obviously, check your version number) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -961,19 +961,15 @@ But if eval is given (QUOTE X), X should not be evaluated. QUOTE is a special fo | ||||||
| that prevents its argument from being evaluated. | that prevents its argument from being evaluated. | ||||||
| A special form differs from a function in two ways. Its arguments are not evaluated | A special form differs from a function in two ways. Its arguments are not evaluated | ||||||
| before the special form sees them. COND, for example, has a very special way of | before the special form sees them. COND, for example, has a very special way of | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| evaluating its arguments by using evcon. The second way which special forms differ | evaluating its arguments by using evcon. The second way which special forms differ | ||||||
| from functions is that they may have an indefinite number of arguments. Special forrrls | from functions is that they may have an indefinite number of arguments. Special forms | ||||||
| have indicators on their property lists called FEXPR and FSUBR for LISP -defined forms | have indicators on their property lists called FEXPR and FSUBR for LISP-defined forms | ||||||
| and machine language coded forms, respectively. | and machine language coded forms, respectively. | ||||||
| 
 | 
 | ||||||
| ``` | ### 2.6 Programming for the Interpreter | ||||||
| 2.6 Programming for the Interpreter |  | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| The purpose of this section is to help the programmer avoid certain common errors. | The purpose of this section is to help the programmer avoid certain common errors. | ||||||
| Example 1 | Example 1: CAR | ||||||
| fn: CAR | fn: CAR | ||||||
| args: ((A B)) | args: ((A B)) | ||||||
| The value is A. Note that the interpreter expects a list of arguments. The one argu- | The value is A. Note that the interpreter expects a list of arguments. The one argu- | ||||||
|  | @ -981,20 +977,18 @@ ment for car is (A B). The extra pair of parentheses is necessary. | ||||||
| One could write (LAMBDA (X) (CAR X)) instead of just CAR. This is correct but | One could write (LAMBDA (X) (CAR X)) instead of just CAR. This is correct but | ||||||
| unnecessary. | unnecessary. | ||||||
| 
 | 
 | ||||||
| ``` | Example 2: CONS | ||||||
| Example 2 |  | ||||||
| fn: CONS | fn: CONS | ||||||
| args: (A (B. C)) | args: (A (B . C)) | ||||||
| The value is cons[^;(^. c)] = (A. (B. C)). | The value is cons[a; cons[b; c]] = (A . (B . C)). | ||||||
| The print program will write this as (A B. C). | The print program will write this as (A B . C). | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| Example (^3) - | Example (^3) - | ||||||
| fn: CONS | fn: CONS | ||||||
| args: ((CAR (QUOTE (A. B))) (CDR (QUOTE (C. D)))) | args: ((CAR (QUOTE (A . B))) (CDR (QUOTE (C . D)))) | ||||||
| The value of this computation will be ((CAR (QUOTE (A. B))). (CDR (QUOTE (C. D)))). | The value of this computation will be ((CAR (QUOTE (A . B))) . (CDR (QUOTE (C . D)))). | ||||||
| This is not what the programmer expected. He expected (CAR (QUOTE (A. B))) to | This is not what the programmer expected. He expected (CAR (QUOTE (A . B))) to | ||||||
| evaluate to A, and expected (A. D) as the value of cons. | evaluate to A, and expected (A . D) as the value of cons. | ||||||
| 
 | 
 | ||||||
| * The interpreter expects a ---- list of arguments. ------- It does not expect a list of expressions | * The interpreter expects a ---- list of arguments. ------- It does not expect a list of expressions | ||||||
| -- that will evaluate to the arguments. Tworcorrect ways of writing this function are listed | -- that will evaluate to the arguments. Tworcorrect ways of writing this function are listed | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
|             [beowulf.host :refer [ASSOC ATOM CAAR CAADR CADAR CADDR CADR CAR CDR |             [beowulf.host :refer [ASSOC ATOM CAAR CAADR CADAR CADDR CADR CAR CDR | ||||||
|                                   CONS ERROR GET LIST NUMBERP PAIRLIS traced?]] |                                   CONS ERROR GET LIST NUMBERP PAIRLIS traced?]] | ||||||
|             [beowulf.oblist :refer [*options* NIL]] |             [beowulf.oblist :refer [*options* NIL]] | ||||||
|  |             [clojure.string :as s] | ||||||
|             [clojure.tools.trace :refer [deftrace]]) |             [clojure.tools.trace :refer [deftrace]]) | ||||||
|   (:import [beowulf.cons_cell ConsCell] |   (:import [beowulf.cons_cell ConsCell] | ||||||
|            [clojure.lang Symbol])) |            [clojure.lang Symbol])) | ||||||
|  | @ -48,6 +49,10 @@ | ||||||
|    functions which call EVAL/APPLY but do not know about depth." |    functions which call EVAL/APPLY but do not know about depth." | ||||||
|   0) |   0) | ||||||
| 
 | 
 | ||||||
|  | (defn- trace-indent | ||||||
|  |   ([] (trace-indent *depth*)) | ||||||
|  |   ([d] (s/join (repeat d " ")))) | ||||||
|  | 
 | ||||||
| (def find-target | (def find-target | ||||||
|   (memoize |   (memoize | ||||||
|    (fn [target body] |    (fn [target body] | ||||||
|  | @ -101,17 +106,17 @@ | ||||||
|                                                   (CADR expr) |                                                   (CADR expr) | ||||||
|                                                   vars env depth)] |                                                   vars env depth)] | ||||||
|                                          (when (traced? 'PROG) |                                          (when (traced? 'PROG) | ||||||
|                                            (println "  PROG:RETURN: Returning "  |                                            (println "  PROG:RETURN: Returning " | ||||||
|                                                     val) |                                                     val)) | ||||||
|                                            (make-cons-cell |                                          (make-cons-cell | ||||||
|                                             '*PROGRETURN* |                                           '*PROGRETURN* | ||||||
|                                             val))) |                                           val)) | ||||||
|                                 SET (let [var (prog-eval (CADR expr) |                                 SET (let [var (prog-eval (CADR expr) | ||||||
|                                                          vars env depth) |                                                          vars env depth) | ||||||
|                                           val (prog-eval (CADDR expr) |                                           val (prog-eval (CADDR expr) | ||||||
|                                                          vars env depth)] |                                                          vars env depth)] | ||||||
|                                       (when (traced? 'PROG) |                                       (when (traced? 'PROG) | ||||||
|                                         (println "  PROG:SET: Setting "  |                                         (println "  PROG:SET: Setting " | ||||||
|                                                  var " to " val)) |                                                  var " to " val)) | ||||||
|                                       (swap! vars |                                       (swap! vars | ||||||
|                                              assoc |                                              assoc | ||||||
|  | @ -195,7 +200,7 @@ | ||||||
|                   (println "Program:") |                   (println "Program:") | ||||||
|                   (pretty-print program))) ;; for debugging |                   (pretty-print program))) ;; for debugging | ||||||
|     (loop [cursor body] |     (loop [cursor body] | ||||||
|       (let [step (.getCar cursor)] |       (let [step (if (= NIL cursor) NIL (.getCar cursor))] | ||||||
|         (when trace (do (println "Executing step: " step) |         (when trace (do (println "Executing step: " step) | ||||||
|                         (println "  with vars: " @vars))) |                         (println "  with vars: " @vars))) | ||||||
|         (cond (= cursor NIL) NIL |         (cond (= cursor NIL) NIL | ||||||
|  | @ -228,7 +233,7 @@ | ||||||
|   with these `args` at this depth." |   with these `args` at this depth." | ||||||
|   [function-symbol args depth] |   [function-symbol args depth] | ||||||
|   (when (traced? function-symbol) |   (when (traced? function-symbol) | ||||||
|     (let [indent (apply str (repeat depth "-"))] |     (let [indent (trace-indent depth)] | ||||||
|       (println (str indent "> " function-symbol " " args))))) |       (println (str indent "> " function-symbol " " args))))) | ||||||
| 
 | 
 | ||||||
| (defn- trace-response | (defn- trace-response | ||||||
|  | @ -236,10 +241,12 @@ | ||||||
|    `function-symbol` at this depth." |    `function-symbol` at this depth." | ||||||
|   [function-symbol response depth] |   [function-symbol response depth] | ||||||
|   (when (traced? function-symbol) |   (when (traced? function-symbol) | ||||||
|     (let [indent (apply str (repeat depth "-"))] |     (let [indent (apply str (trace-indent depth))] | ||||||
|       (println (str "<" indent " " function-symbol " " response)))) |       (println (str "<" indent " " function-symbol " " response)))) | ||||||
|   response) |   response) | ||||||
| 
 | 
 | ||||||
|  | ;;;; Support functions for interpreter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||||
|  | 
 | ||||||
| (defn value | (defn value | ||||||
|   "Seek a value for this symbol `s` by checking each of these indicators in |   "Seek a value for this symbol `s` by checking each of these indicators in | ||||||
|    turn." |    turn." | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
|             [beowulf.read :refer [READ]] |             [beowulf.read :refer [READ]] | ||||||
|             [clojure.test :refer [deftest is testing use-fixtures]])) |             [clojure.test :refer [deftest is testing use-fixtures]])) | ||||||
| 
 | 
 | ||||||
| (defn- reps | (defn reps | ||||||
|   "'Read eval print string', or 'read eval print single'. |   "'Read eval print string', or 'read eval print single'. | ||||||
|    Reads and evaluates one input string, and returns the |    Reads and evaluates one input string, and returns the | ||||||
|    output string." |    output string." | ||||||
|  | @ -156,8 +156,11 @@ | ||||||
| ;;                      '(X WROTE Y))")] | ;;                      '(X WROTE Y))")] | ||||||
| ;;       (is (= actual expected))))) | ;;       (is (= actual expected))))) | ||||||
| 
 | 
 | ||||||
|  | ;; this works just fine in the REPL provided PROG is traced, but does not work | ||||||
|  | ;; if PROG is not traced (and doesn't work in the test harness either way) | ||||||
| (deftest prog-tests | (deftest prog-tests | ||||||
|   (testing "PROG" |   (testing "PROG" | ||||||
|  |     ;; (reps "(TRACE 'PROG)") | ||||||
|     (let [expected "5" |     (let [expected "5" | ||||||
|           actual (reps "(PROG (X) |           actual (reps "(PROG (X) | ||||||
|     (SETQ X 1) |     (SETQ X 1) | ||||||
|  | @ -208,8 +211,7 @@ | ||||||
|   (testing "FSUBR/CONC" |   (testing "FSUBR/CONC" | ||||||
|     (reps "(SETQ P (RANGE 1 4))") |     (reps "(SETQ P (RANGE 1 4))") | ||||||
|     (reps "(SETQ Q (RANGE 5 8))") |     (reps "(SETQ Q (RANGE 5 8))") | ||||||
|     (reps "(SETQ R (RANGE 9 12))") |     (reps "(SETQ R (RANGE 9 12))")  | ||||||
|     (reps "(CONC P Q R)") |  | ||||||
|     (let [expected "(1 2 3 4 5 6 7 8 9 10 11 12)" |     (let [expected "(1 2 3 4 5 6 7 8 9 10 11 12)" | ||||||
|           actual (reps "X")] |           actual (reps "(CONC P Q R)")] | ||||||
|       (is (= actual expected))))) |       (is (= actual expected))))) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue