write-ups-challenges-2021-2022/restrictive-racket/validate.rkt

43 lines
1.4 KiB
Racket
Raw Permalink Normal View History

2021-12-02 23:33:26 +00:00
; This will be used on the server to validate all source code by the participants before running it
; Allowed procedures and special-forms will vary with each challenge
#lang racket
(require "challenge.rkt")
(require "either.rkt")
(provide validate run)
(define (validate str allowed)
(call/cc
(lambda (c)
(call-with-exception-handler
(lambda (e)
(c (left (exn-message e))))
(lambda ()
(define expr (read (open-input-string str)))
(if (check-allowed expr allowed)
(right expr)
(left "Error: you used a procedure, special form or variable name that has been disabled.")))))))
(define (check-allowed expr allowed)
(if (pair? expr)
(andmap (lambda (x) (check-allowed x allowed)) expr)
(or (not (symbol? expr)) (member expr allowed))))
; Allowing for functions with multiple arguments is something I leave for the future generation to implement
; It should be quite trivial add
(define (run challenge code)
(call/cc
(lambda (c)
(call-with-exception-handler
(lambda (e)
(c (left (exn-message e))))
(lambda ()
(define input (challenge-input challenge))
(define func (eval code (make-base-namespace)))
(define res (map (lambda (in) (apply func (list in))) input))
(if (equal? res (challenge-output challenge))
(right "")
(left res)))))))