75 lines
1.9 KiB
Racket
75 lines
1.9 KiB
Racket
|
#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)
|