EWTD

Interpretator for OCHKO Lang

Dec 19th, 2020 (edited)
858
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (define exit #f)
  2. (define (use-assertions)
  3.   (call-with-current-continuation
  4.    (lambda (cc)
  5.      (set! exit cc))))
  6. (use-assertions)
  7. (define-syntax assert-with-message
  8.   (syntax-rules ()
  9.     ((_ expression message)
  10.      (if (not expression)
  11.          (begin
  12.            (display message)
  13.            (newline)
  14.            (exit))))))
  15. (define (interpret commands stack)
  16.   (define exit-continuations '())
  17.   (define commands-length (vector-length commands))
  18.   ;returns index of end for current function/if
  19.   (define (find-end pos)
  20.     (define (find-pos plus_elem minus_elem counter index)
  21.       (if (and (not (= index pos)) (= counter 0))
  22.           index
  23.           (if (= index commands-length)
  24.               0
  25.               (if (equal? (vector-ref commands index) plus_elem)
  26.                   (find-pos plus_elem minus_elem (+ counter 1) (+ index 1))
  27.                   (if (equal? (vector-ref commands index) minus_elem)
  28.                       (find-pos plus_elem minus_elem (- counter 1) (+ index 1))
  29.                       (find-pos plus_elem minus_elem counter (+ index 1)))))))
  30.     (if (equal? (vector-ref commands pos) 'define)
  31.         (- (find-pos 'define 'end  0 pos) 1)
  32.         (if (equal? (vector-ref commands pos) 'if)
  33.             (- (find-pos 'if 'endif 0 pos) 1)
  34.             -1)))
  35.   ;returns index of else for current if
  36.   (define (find-else pos)
  37.     (define (find-pos counter index end-index)
  38.       (if (and (not (= index pos)) (= counter 0))
  39.           index
  40.           (if (= index end-index)
  41.               -1
  42.               (let ((current-command (vector-ref commands index)))
  43.                 (cond
  44.                   ((equal? current-command 'if) (find-pos (+ counter 1) (+ index 1) end-index))
  45.                   ((equal? current-command 'endif) (find-pos (- counter 1) (+ index 1) end-index))
  46.                   ((equal? current-command 'else) (if (= counter 1) index (find-pos counter (+ index 1) end-index)))
  47.                   (else (find-pos counter (+ index 1) end-index)))))))
  48.     (if (equal? (vector-ref commands pos) 'if)
  49.         (find-pos 0 pos (find-end pos))
  50.         -1))
  51.   ;returns dictionary of functions
  52.   (define (parse-scope begin_pos end_pos)
  53.     (define (_iter index result)
  54.       (if (= index end_pos)
  55.           result
  56.           (let ((current-command (vector-ref commands index)))
  57.             (cond
  58.               ((equal? current-command 'define) (let ((end-index (find-end index)))
  59.                                                   (if (= end-index -1)
  60.                                                       (assert-with-message #f "cant find <end> for <define>")
  61.                                                       (_iter (+ end-index 1) (cons (list (vector-ref commands (+ index 1)) (list (+ index 2) end-index)) result)))))
  62.               ((equal? current-command 'if) (let ((end-index (find-end index)))
  63.                                               (if (= end-index -1)
  64.                                                   (assert-with-message #f "can't find <endif> for <if>")
  65.                                                   (_iter (+ end-index 1) result))))
  66.               (else (_iter (+ index 1) result))))))
  67.     (_iter begin_pos '()))
  68.   ;merges scopes, if element found in both scopes rhs_scope overrides lhs_scope
  69.   (define (merge-scopes lhs_scope rhs_scope)
  70.     (define (_iter collectable result)
  71.       (if (null? collectable)
  72.           result
  73.           (if (equal? (assq (caar collectable) result) #f)
  74.               (_iter (cdr collectable) (cons (car collectable) result))
  75.               (_iter (cdr collectable) result))))
  76.     (_iter lhs_scope rhs_scope))
  77.   ;do stuff:)
  78.   (define (main index end-index stack scope)
  79.     (if (= index end-index)
  80.         stack
  81.         (let ((current-command (vector-ref commands index)))
  82.           (cond
  83.             ((number? current-command) (main (+ index 1) end-index (cons current-command stack) scope ))
  84.             ((equal? current-command '+) (let ((stack-length (length stack)))
  85.                                            (if (< stack-length 2)
  86.                                                (assert-with-message #f "+ cant be applied, cause stack length < 2")
  87.                                                (main (+ index 1) end-index (cons (+ (car stack) (cadr stack)) (cddr stack)) scope ))))
  88.             ((equal? current-command '-) (let ((stack-length (length stack)))
  89.                                            (if (< stack-length 2)
  90.                                                (assert-with-message #f "- cant be applied, cause stack length < 2")
  91.                                                (main (+ index 1) end-index (cons (- (cadr stack) (car stack)) (cddr stack)) scope ))))
  92.             ((equal? current-command '*) (let ((stack-length (length stack)))
  93.                                            (if (< stack-length 2)
  94.                                                (assert-with-message #f "* cant be applied, cause stack length < 2")
  95.                                                (main (+ index 1) end-index (cons (* (car stack) (cadr stack)) (cddr stack)) scope ))))
  96.             ((equal? current-command '/) (let ((stack-length (length stack)))
  97.                                            (if (< stack-length 2)
  98.                                                (assert-with-message #f "/ cant be applied, cause stack length < 2")
  99.                                                (main (+ index 1) end-index (cons (/ (cadr stack) (car stack)) (cddr stack)) scope ))))
  100.             ((equal? current-command 'mod) (let ((stack-length (length stack)))
  101.                                              (if (< stack-length 2)
  102.                                                  (assert-with-message #f "mod cant be applied, cause stack length < 2")
  103.                                                  (main (+ index 1) end-index (cons (remainder (cadr stack) (car stack)) (cddr stack)) scope ))))
  104.             ((equal? current-command 'and) (let ((stack-length (length stack)))
  105.                                              (if (< stack-length 2)
  106.                                                  (assert-with-message #f "and cant be applied, cause stack length < 2")
  107.                                                  (main (+ index 1) end-index (cons (and (car stack) (cadr stack)) (cddr stack)) scope))))
  108.             ((equal? current-command 'or) (let ((stack-length (length stack)))
  109.                                             (if (< stack-length 2)
  110.                                                 (assert-with-message #f "or cant be applied, cause stack length < 2")
  111.                                                 (main (+ index 1) end-index (cons (- (car stack) (cadr stack)) (cddr stack)) scope))))
  112.             ((equal? current-command '>) (let ((stack-length (length stack)))
  113.                                            (if (< stack-length 2)
  114.                                                (assert-with-message #f "> cant be applied, cause stack length < 2")
  115.                                                (main (+ index 1) end-index (cons (> (cadr stack) (car stack)) (cddr stack)) scope))))
  116.             ((equal? current-command '<) (let ((stack-length (length stack)))
  117.                                            (if (< stack-length 2)
  118.                                                (assert-with-message #f "< cant be applied, cause stack length < 2")
  119.                                                (main (+ index 1) end-index (cons (< (cadr stack) (car stack)) (cddr stack)) scope))))
  120.             ((equal? current-command '=) (let ((stack-length (length stack)))
  121.                                            (if (< stack-length 2)
  122.                                                (assert-with-message #f "= cant be applied, cause stack length < 2")
  123.                                                (main (+ index 1) end-index (cons (= (car stack) (cadr stack)) (cddr stack)) scope))))
  124.             ((equal? current-command 'swap) (let ((stack-length (length stack)))
  125.                                               (if (< stack-length 2)
  126.                                                   (assert-with-message #f "swap cant be applied, cause stack length < 2")
  127.                                                   (main (+ index 1) end-index (append (list (cadr stack) (car stack)) (cddr stack)) scope))))
  128.             ((equal? current-command 'over) (let ((stack-length (length stack)))
  129.                                               (if (< stack-length 2)
  130.                                                   (assert-with-message #f "over cant be applied, cause stack length < 2")
  131.                                                   (main (+ index 1) end-index (cons (cadr stack) stack) scope))))
  132.             ((equal? current-command 'rot) (let ((stack-length (length stack)))
  133.                                              (if (< stack-length 3)
  134.                                                  (assert-with-message #f "rot cant be applied, cause stack length < 3")
  135.                                                  (main (+ index 1) end-index (append (list (caddr stack) (cadr stack) (car stack)) (cdddr stack)) scope))))
  136.             ((equal? current-command 'depth) (let ((stack-length (length stack)))
  137.                                                (main (+ index 1) end-index (cons stack-length stack) scope)))
  138.             ((equal? current-command 'drop) (let ((stack-length (length stack)))
  139.                                               (if (< stack-length 1)
  140.                                                   (assert-with-message #f "drop cant be applied, cause stack length < 1")
  141.                                                   (main (+ index 1) end-index (cdr stack) scope))))
  142.             ((equal? current-command 'dup) (let ((stack-length (length stack)))
  143.                                              (if (< stack-length 1)
  144.                                                  (assert-with-message #f "dup cant be applied, cause stack length < 1")
  145.                                                  (main (+ index 1) end-index (append (list (car stack) (car stack)) (cdr stack)) scope))))
  146.             ((equal? current-command 'not) (let ((stack-length (length stack)))
  147.                                              (if (< stack-length 1)
  148.                                                  (assert-with-message #f "not cant be applied, cause stack length < 1")
  149.                                                  (main (+ index 1) end-index (cons (not (car stack)) (cdr stack)) scope))))
  150.             ((equal? current-command 'neg) (let ((stack-length (length stack)))
  151.                                              (if (< stack-length 1)
  152.                                                  (assert-with-message #f "neg cant be applied, cause stack length < 1")
  153.                                                  (main (+ index 1) end-index (cons (- (car stack)) (cdr stack)) scope))))
  154.             ((equal? current-command 'define) (let ((end-pos (find-end index)))
  155.                                                 (if (= end-pos -1)
  156.                                                     (assert-with-message #f "funciton hasn't got an <end>")
  157.                                                     (main (+ end-pos 1) end-index stack scope))))
  158.             ((equal? current-command 'if) (let ((end-pos (find-end index)) (else-index (find-else index)))
  159.                                             (if (= end-pos -1)
  160.                                                 (assert-with-message #f "<if> hasn't got an <end>")
  161.                                                 (if (car stack)
  162.                                                     (main (+ end-pos 1) end-index
  163.                                                           (main (+ 1 index) end-pos (cdr stack)
  164.                                                                 (merge-scopes scope (parse-scope (+ index 1) (if (= else-index -1) end-index else-index))))
  165.                                                           scope)
  166.                                                     (if (= else-index -1)
  167.                                                         (main (+ end-pos 1) end-index (cdr stack) scope)
  168.                                                         (main (+ end-pos 1) end-index
  169.                                                               (main (+ else-index 1) end-pos
  170.                                                                     (cdr stack)
  171.                                                                     (merge-scopes scope (parse-scope (+ index 1) end-pos)))
  172.                                                               scope))))))
  173.             ;exit on top context in stack
  174.             ((equal? current-command 'exit) ((car exit-continuations) stack))
  175.             ;function call will remembering of current context for possible exit
  176.             ((not (equal? (assq current-command scope) #f))
  177.              (let* ((pair (cadr (assq current-command scope)))
  178.                     (result (call-with-current-continuation (lambda (cc) (begin
  179.                                                                            (set! exit-continuations (cons cc exit-continuations))
  180.                                                                            (main (car pair) (cadr pair) stack (merge-scopes scope (parse-scope (car pair) (cadr pair)))))))))
  181.                (begin (set! exit-continuations (cdr exit-continuations)) (main (+ index 1) end-index result scope))))
  182.             (else (assert-with-message #f (string-append "cant interpret <" (symbol->string current-command) ">")))))))
  183.   (main 0  commands-length stack (parse-scope 0 commands-length )))
  184. (interpret #(2 3 * 4 5 * +) '())
  185. (interpret #(   define -- 1 - end
  186.                 5 -- --      ) '())
  187. (interpret #(   define abs
  188.                     dup 0 <
  189.                     if neg endif
  190.                 end
  191.                  9 abs
  192.                 -9 abs      ) (quote ()))
  193. (interpret #(   define =0? dup 0 = end
  194.                 define <0? dup 0 < end
  195.                 define signum
  196.                     =0? if exit endif
  197.                     <0? if drop -1 exit endif
  198.                     drop
  199.                     1
  200.                 end
  201.                  0 signum
  202.                 -5 signum
  203.                 10 signum       ) (quote ()))
  204. (interpret #(   define -- 1 - end
  205.                 define =0? dup 0 = end
  206.                 define =1? dup 1 = end
  207.                 define factorial
  208.                     =0? if drop 1 exit endif
  209.                     =1? if drop 1 exit endif
  210.                     dup --
  211.                     factorial
  212.                     *
  213.                 end
  214.                 0 factorial
  215.                 1 factorial
  216.                 2 factorial
  217.                 3 factorial
  218.                 4 factorial     ) (quote ()))
  219. (interpret #(   define =0? dup 0 = end
  220.                 define =1? dup 1 = end
  221.                 define -- 1 - end
  222.                 define fib
  223.                     =0? if drop 0 exit endif
  224.                     =1? if drop 1 exit endif
  225.                     -- dup
  226.                     -- fib
  227.                     swap fib
  228.                     +
  229.                 end
  230.                 define make-fib
  231.                     dup 0 < if drop exit endif
  232.                     dup fib
  233.                     swap --
  234.                     make-fib
  235.                 end
  236.                 10 make-fib     ) (quote ()))
  237. (interpret #(   define =0? dup 0 = end
  238.                 define gcd
  239.                     =0? if drop exit endif
  240.                     swap over mod
  241.                     gcd
  242.                 end
  243.                 90 99 gcd
  244.                 234 8100 gcd    ) '())
  245.  
  246.    
  247.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×