Skip to content

Instantly share code, notes, and snippets.

@gfreivasc
Last active February 27, 2020 19:37
Show Gist options
  • Save gfreivasc/9768c238e03d2e2211b1c5d90ee6183b to your computer and use it in GitHub Desktop.
Save gfreivasc/9768c238e03d2e2211b1c5d90ee6183b to your computer and use it in GitHub Desktop.
(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