Advertisement
Guest User

LMC

a guest
Jul 18th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 14.80 KB | None | 0 0
  1. ;;;Duretto Benito Francesco Antonio 829795
  2. ;;;Stampa il messaggio di errore corretto
  3. (defun err* (err index)
  4.   (cond
  5.    ((= err 0)
  6.     (format
  7.      t
  8.      "Error: File maximum contain 100 instruction,
  9. Instriction in this File are: ~S"
  10.      index))
  11.    ((= err 1)
  12.     (format t "Error: Unexpected number of element, Line: ~S" index))
  13.    ((= err 2)
  14.     (format t "Error: Label cant be a number, Line: ~S" index))
  15.    ((= err 3)
  16.     (format t "Error: Instruction isnt valid, Line: ~S" index))
  17.    ((= err 4)
  18.     (format t "Error: Parameter value isnt between 0-999, Line: ~S" index))
  19.    ((= err 5)
  20.     (format
  21.      t
  22.      "Error: Unknow Parameter value, Integer or label required. Line: ~S"
  23.      index))
  24.    ((= err 6)
  25.     (format t "Error: Parameter value isnt between 0-99, Line: ~S" index))
  26.    ((= err 7)
  27.     (format t "Error: An element cant be an instruction, Line: ~S" index))
  28.    ((= err 8)
  29.     (format t "Error: Label already defined, Line: ~S" index))
  30.    ((= err 9)
  31.     (format t "Error: Label not defined, Line: ~S" index))
  32.    ((= err 11)
  33.     (format t "Error: Value in memory Unexpected: Value ~S" index))
  34.    ((= err 12)
  35.     (format t "Error: The elements in the input list are not enough "))
  36.    ((= err 13)
  37.     (format t "Error: Illegal input: ~S" index))
  38.    (t (format t "Unknown Error")))
  39.   nil)
  40.  
  41. ;;;leggo il file linea per linea
  42. (defun get-file (filename)
  43.   (with-open-file (stream filename)
  44.     (labels ((read-recursively (read-so-far)
  45.                (let ((line (read-line stream nil 'eof)))
  46.                  (if (eq line 'eof)
  47.                      (reverse read-so-far)
  48.                    ;;creo una lista con tutte le linee del file ben formattate
  49.                      (read-recursively (cons (filter line) read-so-far))))))
  50.       (read-recursively ()))))
  51.  
  52. ;;;elimino i commenti
  53. (defun comment-remove (str)
  54.   (let ((position (search "//" str)))
  55.     (if position (subseq str 0 position) str)))
  56.  
  57. ;;;filtro la linea togliendo
  58. ;;;gli spazi inutili e i caratteri speciali
  59. (defun filter (line)
  60.   (let ((str
  61.          (string-trim
  62.           '(#\Space )
  63.           (comment-remove
  64.            (string-downcase
  65.             (string-trim
  66.              '(#\Space #\Newline )
  67.              (remove
  68.               '(#\Newline #\Page #\Return #\Rubout #\Linefeed #\Backspace)
  69.               (substitute #\Space #\Tab line))))))))
  70.     (if (string= "" str) nil (flatten(splitter " " str)))))
  71.  
  72. ;;;divido la stringa senza commenti
  73. ;;;in stringhe e formo una lista
  74. (defun splitter (X str)
  75.   (let ((position (search X str)))
  76.     (if
  77.         position
  78.         (list
  79.          (subseq str 0 position)
  80.          (splitter X (string-trim X (subseq str (+ position 1)))))
  81.       str)))
  82.  
  83.  
  84. (defun flatten (lista)
  85.   (cond
  86.     ((null lista) nil)
  87.     ((atom lista) (list lista))
  88.     (t (append (flatten (car lista)) (flatten (cdr lista))))))
  89.  
  90. ;;;carico un file e trasformo le istruzioni in codice macchina
  91. (defun lmc-load (X)
  92.   (let ((instructions (remove nil (get-file X)))
  93.         (label-list (take-label nil (remove nil (get-file X)) 0)))
  94.     ;;controllo se le label sono corrette
  95.     (if (control-label-defined label-list 0)
  96.         (let
  97.             ((mem
  98.               (delete-label-instruction
  99.                label-list
  100.                instructions)))
  101.           ;;controllo se la lunghezza della memoria sia massimo
  102.           ;;di 100 istruzioni
  103.           (if (<= (length mem) 100)
  104.               (if (control mem label-list 0)
  105.                   (append
  106.                    ;;traduco le istruzioni in linguaggio macchina
  107.                    (assembler mem label-list 0)
  108.                    (make-list (- 100 (length mem)) :initial-element '0))
  109.                 nil)
  110.             (err* 0 (length mem))))
  111.       nil)))
  112.  
  113. ;;ritorna il valore macchina se l'elemento e' una istruzione
  114. ;;altrimenti nil
  115. (defun is-instruction (Element)
  116.   (cond
  117.    ((string= Element "add") 100)
  118.    ((string= Element "sub") 200)
  119.    ((string= Element "sta") 300)
  120.    ((string= Element "lda") 500)
  121.    ((string= Element "bra") 600)
  122.    ((string= Element "brz") 700)
  123.    ((string= Element "brp") 800)
  124.    ((string= Element "dat") 0)
  125.    (T (is-instruction1 Element))))
  126.  
  127. (defun is-instruction1 (Element)
  128.   (cond
  129.    ((string= Element "inp") 901)
  130.    ((string= Element "out") 902)
  131.    ((string= Element "hlt") 0)
  132.    (T nil)))
  133.  
  134.  
  135.  
  136. ;;;prende il primo elemento di ogni istruzione
  137. ;;;con il rispettivo indice
  138. ;;;solo se non risulta essere un comando predefinito
  139. ;;;e crea una lista
  140. (defun take-label (lista-label instructions index)
  141.   (cond
  142.    ((null instructions) nil)
  143.    ((is-instruction (car (car instructions)))
  144.     (take-label lista-label (cdr instructions) (+ index 1)))
  145.    ((null (cdr instructions)) (list (list (car (car instructions)) index)))
  146.    (t
  147.     (append
  148.      lista-label
  149.      (list
  150.       (list (car (car instructions)) index))
  151.      (take-label lista-label (cdr instructions) (+ index 1))))))
  152.  
  153. ;;;cerca una label nella lista delle label
  154. ;;;se presente ritorna il valore di indice
  155. ;;;altrimenti ritorna nil
  156. (defun search-label-defined (label lista-label)
  157.   (if lista-label
  158.       (if (string= label (car (car lista-label)))
  159.           (car(cdr (car lista-label)))
  160.         (search-label-defined label (cdr lista-label)))
  161.     nil))
  162.  
  163. ;;;controlla se le label acquisite da take-label sono corrette
  164. (defun control-label-defined (list1 index)
  165.   (if list1
  166.       (cond
  167.        ;;controlla se la label e' un numero
  168.        ((numberp (read-from-string (car (car list1)))) (err* 2 index))
  169.        ;;controla se la label e' gia' stata definita
  170.        ((search-label-defined
  171.          (car (car list1))
  172.          (cdr list1))(err* 8 index))
  173.        (t (control-label-defined
  174.            (cdr list1)
  175.            (+ index 1))))
  176.     t))
  177.  
  178. ;;;elimina tutte le label nelle istruzioni
  179. ;;;per scremare il numero degli elementi
  180. (defun delete-label-instruction (label-list instructions)
  181.   (cond
  182.    ((null label-list) instructions)
  183.    ((search-label-defined
  184.      (car (car instructions))
  185.      label-list)
  186.     (append
  187.      (list (cdr (car instructions)))
  188.      (delete-label-instruction
  189.       (cdr label-list)
  190.       (cdr instructions))))
  191.    (t (append
  192.        (list (car instructions))
  193.        (delete-label-instruction label-list (cdr instructions))))))
  194.  
  195. ;;;controlla tutte le istruzioni nella memoria
  196. ;;;quando l'istruzione e'
  197. ;;; da 2 elementi fa il controllo da 2 elementi
  198. ;;; da 1 elemento fa il controllo da 1 elemento
  199. ;;; altrimenti errore
  200. (defun control (instructions label-list index)
  201.   (cond
  202.    ((null instructions) t)
  203.    ((= (length (car instructions)) 2)
  204.     (if (controllo2 (car instructions) label-list index)
  205.         (control
  206.          (cdr instructions)
  207.          label-list
  208.          (+ index 1)) nil))
  209.    ((= (length (car instructions)) 1)
  210.     (if (controllo1 (car instructions) index)
  211.         (control
  212.          (cdr instructions)
  213.          label-list
  214.          (+ index 1)) nil))
  215.    (t (err* 1 index))))
  216.  
  217.  
  218. ;;;controlla che la istruzione da due elementi sia corretta
  219. ;;;ritorna true o err*
  220. (defun controllo2 (instruction label-list index)
  221.   (if (is-instruction (car instruction))
  222.       (cond
  223.        ;;controllo se il primo elemento e' una
  224.        ;;istruzione che non preveda parametri
  225.        ((is-instruction1
  226.          (car instruction)) (err* 3 index))
  227.        ;;quando il primo elemento è dat
  228.        ;;il secondo deve necessariamente essere un numero compreso tra 0 e 999
  229.        ((string= (car instruction) "dat")
  230.           (if (numberp
  231.                (read-from-string (car (cdr instruction))))
  232.               ;;then
  233.               (if (and
  234.                    (< (read-from-string (car (cdr instruction))) 1000)
  235.                    (>= (read-from-string (car (cdr instruction))) 0))
  236.                   t (err* 4 index))
  237.             (err* 3 index)))
  238.        ;;il primo elemento e' una una istruzione
  239.        ;;che prevede parametro ed e' diversa da dat
  240.        (t (if
  241.               ;;se la label e' definita ritorna true
  242.               (search-label-defined (car (cdr instruction)) label-list)
  243.               t
  244.             ;;se il parametro e' un numero deve essere necessariamente
  245.             ;;essere compreso tra 0 e 99
  246.             (if (numberp
  247.                  (read-from-string (car (cdr instruction))))
  248.                 (if (and
  249.                      (< (read-from-string (car (cdr instruction))) 100)
  250.                      (>= (read-from-string (car (cdr instruction))) 0))
  251.                     t (err* 6 index))
  252.               (err* 9 index))))) (err* 3 index)))
  253.  
  254. ;;;Quando l'istruzione ha un solo elemento, questo deve essere
  255. ;;; necessariamente una istruzione che non preveda parametri
  256. (defun controllo1 (instruction index)
  257.   (if (or
  258.        (is-instruction1 (car instruction))
  259.        (string= (car instruction) "dat"))
  260.       t (err* 3 index)))
  261.  
  262. ;;;converte la lista di istruzioni in codice macchina
  263. ;;;quando una istruzione ha due elementi fa la somma
  264. ;;;is-instruction + numero o is-instruction + index di label
  265. ;;;quando l'istruzione è singola traduce l'istruzione in codice macchina
  266. ;;;con is-instruction.
  267. (defun assembler (instructions label-list index)
  268.   (cond
  269.    ((= (length (car instructions)) 2)
  270.     (append
  271.      (list
  272.       (+ (is-instruction (car (car instructions)))
  273.          (label-or-number (car(cdr (car instructions))) label-list)))
  274.      (assembler (cdr instructions) label-list (+ index 1))))
  275.    ((= (length (car instructions)) 1)
  276.     (append
  277.      (list
  278.       (is-instruction (car (car instructions))))
  279.      (assembler (cdr instructions) label-list (+ index 1))))
  280.    (t nil)))
  281.  
  282. ;;;se l'elemento e' un numero ritorna il numero
  283. ;;;se l'elemento e' una label ritorna la posizione
  284. ;;;indicata dalla label
  285. (defun label-or-number (element label-list)
  286.  (if (numberp (read-from-string element))
  287.      (read-from-string element)
  288.    (search-label-defined element label-list)))
  289.  
  290.  
  291. ;;;inizializza lo stato e avvia l'esecuzione
  292. (defun lmc-run (file input)
  293.   (compile 'execution-loop);per non generare stack-overflow nel terzo file asm.
  294.   (let ((mem (lmc-load file)))
  295.     (if mem
  296.         (execution-loop
  297.          (list 'state
  298.                :acc 0
  299.                :pc 0
  300.                :mem mem
  301.                :in input
  302.                :out nil
  303.                :flag 'noflag)))))
  304.  
  305. (defun lmc-run* (file input)
  306.   ((lambda (mem)
  307.   (if mem
  308.       (execution-loop
  309.        (list 'state
  310.              :acc 0
  311.              :pc 0
  312.              :mem mem
  313.              :in input
  314.              :out nil
  315.              :flag 'noflag)))
  316.       ) (lmc-load file))
  317.     )
  318.  
  319.  
  320.  
  321. ;;;esegue one-instruction fino a quando non viene ritornato
  322. ;;;un errore o uno stato bloccato con halted-state
  323. (defun execution-loop (initial-state)
  324.   (labels ((execution-cicle (state)
  325.              (cond
  326.               ((null state) nil)
  327.               ((eq (car state) 'halted-state) state)
  328.               (t (execution-cicle (one-instruction state))))))
  329.     (let ((final-state (execution-cicle initial-state)))
  330.       (if final-state
  331.           (format
  332.            nil
  333.            "Execution has been completed succesfully, Output: ~S"
  334.            (if (null (nth (+ (position :out final-state) 1) final-state))
  335.                'empty
  336.              (nth (+ (position :out final-state) 1) final-state))) nil))))
  337.  
  338. ;;;esegue l'istruzione indicata dal Program counter
  339. ;;;altrimenti ritorna errore
  340. (defun one-instruction (state)
  341.   (labels ((get-value (keyword)
  342.              (nth (+ (position keyword state) 1) state))
  343.            (set-value (keyword value)
  344.              (setf (nth (+ 1 (position keyword state)) state) value)))
  345.     (let* ((pc (get-value ':pc));program counter
  346.            (mem (get-value ':mem));la memoria nello stato
  347.            (code (floor (nth pc mem) 100));op_code dell'istruzione
  348.            (arg (mod (nth pc mem) 100));argomento dell'istruzione
  349.            (acc (get-value ':acc));accumulatore
  350.            (in (get-value ':in));lista di input
  351.            (out (get-value ':out));lista di output
  352.            (flag (get-value ':flag));flag di attivazione eventi
  353.            (pc++ (mod (+ pc 1) 100)));incremento pc
  354.       (cond
  355.        ;;istruzione: hlt
  356.        ((= code 0) (append (list 'halted-state) (cdr state)))
  357.        ;;istruzione: add
  358.        ((= code 1)
  359.         (let* ((increment-acc (+ acc (nth arg mem)))
  360.                (set-flag (if (> increment-acc 999) 'flag 'noflag)))
  361.           (set-value :acc (mod increment-acc 1000))
  362.           (set-value :pc pc++)
  363.           (set-value :flag set-flag) state))
  364.        ;;istruzione: sub
  365.        ((= code 2)
  366.         (let* ((decrement-acc (- acc (nth arg mem)))
  367.                (set-flag (if (< decrement-acc 0) 'flag 'noflag)))
  368.           (set-value :acc (mod decrement-acc 1000))
  369.           (set-value :pc pc++)
  370.           (set-value :flag set-flag) state))
  371.        ;;istruzione: sta (store)
  372.        ((= code 3)
  373.         (progn
  374.           (set-value :mem (append
  375.                            (subseq mem 0 arg)
  376.                            (list acc) (subseq mem (+ arg 1))))
  377.           (set-value :pc pc++) state))
  378.        ;;istruzione: lda (load)
  379.        ((= code 5)
  380.         (progn
  381.           (set-value :acc (nth arg mem))
  382.           (set-value :pc pc++) state))
  383.        ;;istruzione: bra (branch)
  384.        ((= code 6)
  385.         (progn (set-value :pc arg) state))
  386.        ;;istruzione: brz (branch if zero)
  387.        ((= code 7)
  388.         (progn (set-value :pc (if (and (= acc 0) (eq flag 'noflag))
  389.                                   arg pc++)) state))
  390.        ;;istruzione: brp (branch if positive)
  391.        ((= code 8)
  392.         (progn (set-value :pc (if (eq flag 'noflag) arg pc++))) state)
  393.        ;;istruzione: inp (input)
  394.        ((and (= code 9) (= arg 1))
  395.         (if (null in) (err* 12 0) ;controllo se la lista di input e' vuota
  396.           (if (and (numberp (car in)) (>= (car in) 0) (< (car in) 1000))
  397.               (progn
  398.                 (set-value :pc pc++)
  399.                 (set-value :acc (car in))
  400.                 (set-value :in (cdr in)) state)
  401.             (err* 13 (car in)))))
  402.        ;;istruzione: out (output)
  403.        ((and (= code 9) (= arg 2))
  404.         (progn
  405.           (set-value :pc pc++)
  406.           (set-value :out (append out (list acc))) state))
  407.        (t (err* 11 (+ (* code 100) arg)))))))
  408.  
  409.  
  410. (defun f (x y)
  411.    ((lambda (a b)
  412.       (+ (* x (quadrato a))
  413.              (* y b)
  414.              (* a b)))
  415.     (+ 1 (* x y))
  416.     (- 1 y)))
  417.  
  418. (defun f (x y)
  419.    (let ((a (+ 1 (* x y)))
  420.          (b (- 1 y))
  421.          )
  422.     (+ (* x (quadrato a))
  423.        (* y b)
  424.      (* a b))))
  425.  
  426. (defun f (x y)
  427. ((lambda (a b)
  428.   (+ (* x (quadrato a))
  429.       (* y b)
  430.       (*a b))
  431.   ) (+ 1 (* x y)) (- 1 y))
  432.  
  433. )
  434.  
  435.  
  436. (defun reduce* (x y)
  437.   (cond
  438.     ((atom y) y)
  439.     (t (reduce* x (funcall x (car y) (when (cdr y) (reduce* x (cdr y))))))
  440.   ))
  441.  
  442.   (defun nopred* (x y)
  443.     (cond
  444.       ((null y) nil)
  445.       ((atom y) (if (ignore-errors (funcall x y)) nil (list y)))
  446.       (t (append (nopred* x (car y)) (nopred* x (cdr y))))))
  447.  
  448.  
  449. const char a = 'a';
  450. char* p = a*;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement