#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 ( ... ) (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)