Last active
February 27, 2020 19:37
-
-
Save gfreivasc/9768c238e03d2e2211b1c5d90ee6183b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns rpn | |
(:require [clojure.edn :as edn])) | |
(deftype Pair [f s]) | |
(defn push' [top value] | |
(Pair. top value)) | |
(defn empty'? [stack] | |
(= stack nil)) | |
(defn pop' [top] | |
(if (empty'? top) nil (.f top))) | |
(defn peek' [top] | |
(if (empty'? top) nil (.s top))) | |
(defn size' [stack] | |
(if (empty'? stack) 0 | |
(+ 1 (size' (pop' stack))))) | |
(defn div' [left right] | |
(defn div-err [] | |
(println "ERR: Cannot divide by zero") | |
left) | |
(if (= right 0) (div-err) | |
(/ left right))) | |
(defn operate [op left right] | |
(cond | |
(= op "+") (+ left right) | |
(= op "-") (- left right) | |
(= op "*") (* left right) | |
(= op "/") (div' left right) | |
:else left)) | |
(defn parseOp [op stack] | |
(defn run-with-left [right cur-stack] | |
(if (empty'? cur-stack) (push' cur-stack right) | |
(push' (pop' cur-stack) (operate op (peek' cur-stack) right)))) | |
(if (empty'? stack) stack | |
(run-with-left (peek' stack) (pop' stack)))) | |
(defn integer'? [s] | |
(try (Integer/parseInt s) | |
true | |
(catch Exception e false))) | |
(defn op? [s] | |
(or (= s "+") (= s "-") (= s "*") (= s "/"))) | |
(defn exit? [s] | |
(= "s" s)) | |
(defn print-stack-top [stack] | |
(defn print-not-last [] | |
(print "> ") | |
(print (peek' stack)) | |
(print "\n")) | |
(defn print-last [] | |
(print ">> ") | |
(print (peek' stack)) | |
(print "\n")) | |
(if (> (size' stack) 1) | |
(print-not-last) | |
(print-last)) | |
(flush) | |
stack) | |
(defn print-stack [stack] | |
(defn print-stack-inner [cur-stack] | |
(when (not (= nil cur-stack)) | |
(print (peek' cur-stack)) | |
(when (not (= nil (pop' cur-stack))) | |
(print " ")) | |
(print-stack-inner (pop' cur-stack)))) | |
(print "[") | |
(print-stack-inner stack) | |
(print "]\n") | |
(flush) | |
stack) | |
(defn runtime [stack] | |
(let [input (read-line)] | |
(cond | |
(integer'? input) (runtime (push' stack (edn/read-string input))) | |
(op? input) (runtime (print-stack-top (parseOp input stack))) | |
(exit? input) nil | |
:else (runtime (print-stack stack))))) | |
(defn -main [] | |
(println "Digite e inicie a operação (s para sair):") | |
(runtime nil)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment