write-ups-challenges-2020-2021/scheming-schemer/first/calculator-app.rkt

75 lines
1.9 KiB
Racket
Raw Permalink Normal View History

2022-11-24 17:03:20 +00:00
#lang r5rs
;This is a simple interpreter for arithmetic expressions
;An expression can be a number, a symbol or a list consisting of an operator and at least one expression
;Variables can be defined using def (e.g., (def a 1))
;Assoc containing defined variables
(define env '())
;Add a variable to the environment
(define (add-variable name value)
(set! env (cons (cons name value) env))
"Variable added!")
;Read a variable from the environment
(define (read-variable name)
(define pair (assq name env))
(if pair
(cdr pair)
(begin
(display "Undefined variable")
(newline))))
;Load the very secret flag
(define (load-flag)
(define flag '())
(call-with-input-file
"flag.txt"
(lambda (input-port)
(let loop ((x (read-char input-port)))
(if (not (eof-object? x))
(begin
(set! flag (cons x flag))
(loop (read-char input-port)))))))
(set! flag (list->string flag))
(add-variable 'flag flag))
;Allowed operators
(define operators '(+ - * /))
;Evaluate an expression of the form (<op> <exp> ... <exp>)
(define (evaluate-pair expression)
(define operator (car expression))
(define arguments (cdr expression))
(cond
((eq? operator 'def)
(add-variable (cadr expression) (evaluate (caddr expression))))
((member (car expression) operators)
(apply (eval operator (scheme-report-environment 5)) (map evaluate arguments)))
(else
"Operator not allowed!")))
;Evaluate any expression
(define (evaluate expression)
(cond
((pair? expression)
(evaluate-pair expression))
((symbol? expression)
(read-variable expression))
(else
expression)))
;Start the read-eval-print loop
(define (read-eval-print)
(display ">> ")
(let*
((expression (read))
(result (evaluate expression)))
(display result)
(newline)
(read-eval-print)))
(load-flag)
(read-eval-print)