#lang racket ; make these definitions available outside this module (provide (all-defined-out)) ; global variable to keep track of variables (define variables '()) ; procedure to add or redefine a variable to the top-level environment (define (add-var var value) (define (explore lst) (cond ((null? lst) (list (list var value))) ((eq? (caar lst) var) (cons (list var value) (cdr lst))) (else (cons (car lst) (explore (cdr lst)))))) (set! variables (explore variables))) ; returns a pair (variable value) or #f if no such variable (define (find-var var) (define (explore lst) (cond ((null? lst) #f) ((eq? (caar lst) var) (car lst)) (else (explore (cdr lst))))) (explore variables)) ; An association list indicating what Racket procedure to call for each ; Python function (define functions '((math.sin . sin) (math.cos . cos) (math.tan . tan) (math.log . log) (math.exp . exp) (abs . abs) (float . exact->inexact) (math.ceil . exact-ceiling) (math.floor . exact-floor) (math.sqrt . sqrt))) ; converts a string to a list of tokens; uses special tokens lparen, rparen ; and comma for ( ) , (define (tokenize str) (let ([re "[a-zA-Z_][a-zA-Z0-9_.]*|[*][*]|==|<=|>=|!=|//|[-+*/%'(),<>=]|[^-+*/<>='(),^a-zA-Z_]+"]) (define (is-string s) (and (>= (string-length s) 1) (equal? "\"" (substring s 0 1)))) (define (expand s) (regexp-match* re s)) (define (to-symbol s) (let ((n (string->number s))) (cond (n n) ((equal? s "(") 'lparen) ((equal? s ")") 'rparen) ((equal? s ",") 'comma) ((equal? s "True") #t) ((equal? s "False") #f) (else (string->symbol s))))) (define (process s) (if (is-string s) (list (substring s 1 (- (string-length s) 1))) (map to-symbol (foldr append '() (map expand (regexp-split "[ \t\r]+" s)))))) (foldr append '() (map process (regexp-match* "[^\"]+|\"[^\"]*\"" str)))))