fisl

fisl is scheme lox
git clone git://git.alexkarle.com.com/fisl
Log | Files | Refs | README | LICENSE

commit 8033151ca2d0834aa4fd41541dd13a59257ced00 (patch)
parent f91e1c8b88c9b413e0ac2a23984b7ea006f8b187
Author: Alex Karle <alex@alexkarle.com>
Date:   Sat, 29 Oct 2022 22:44:05 -0400

interpreter: Add basic runtime error handling

This should catch things like comparing a string to a number, but it
won't handle it very gracefully (I still need to grok call/cc!)

Diffstat:
Minterpreter.scm | 58+++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/interpreter.scm b/interpreter.scm @@ -16,6 +16,15 @@ ((null? a) #f) (else (equal? a b)))) + (define (assert-num op x) + ; TODO: use call/cc to not abort the process + (or (number? x) (die (format "Operand must be a number ~A ~A" op x)))) + + (define (assert-nums op x y) + ; TODO: use call/cc to not abort the process + (or (and (number? x) (number? y)) + (die (format "Operands must be numbers ~A ~A ~A" x op y)))) + (define (evaluate expr) ; TODO: put these on the types themselves? like methods (cond @@ -25,33 +34,48 @@ ((unary? expr) (let ((right (evaluate (unary-right expr))) (op (token-type (unary-operator expr)))) - (cond - ((eq? op 'BANG) (truthy? right)) - ((eq? op 'MINUS) (- right)) - ((die (format "Unknown unary op ~A" op)))))) + (case op + ((BANG) (not (truthy? right))) + ((MINUS) + (assert-num op right) + (- right)) + (else die (format "Unknown unary op ~A" op))))) ((binary? expr) (let ((left (evaluate (binary-left expr))) (right (evaluate (binary-right expr))) (op (token-type (binary-operator expr)))) - (cond - ((eq? op 'GREATER) (> left right)) - ((eq? op 'GREATER_EQUAL) (>= left right)) - ((eq? op 'LESS) (< left right)) - ((eq? op 'LESS_EQUAL) (<= left right)) - ((eq? op 'BANG_EQUAL) (not (lox-equal? left right))) - ((eq? op 'EQUAL_EQUAL) (lox-equal? left right)) - ((eq? op 'MINUS) (- left right)) - ((eq? op 'PLUS) + (case op + ((GREATER) + (assert-nums op left right) + (> left right)) + ((GREATER_EQUAL) + (assert-nums op left right) + (>= left right)) + ((LESS) + (assert-nums op left right) + (< left right)) + ((LESS_EQUAL) + (assert-nums op left right) + (<= left right)) + ((BANG_EQUAL) (not (lox-equal? left right))) + ((EQUAL_EQUAL) (lox-equal? left right)) + ((MINUS) + (assert-nums op left right) + (- left right)) + ((PLUS) (cond ((and (string? left) (string? right)) (string-append left right)) ((and (number? left) (number? right)) (+ left right)) - (else (die (format "Bad types for plus ~A") expr)))) - ((eq? op 'SLASH) (/ left right)) - ((eq? op 'STAR) (* left right)) + (else (die (format "Bad types for plus ~A" expr))))) + ((SLASH) + (assert-nums op left right) + (/ left right)) + ((STAR) + (assert-nums op left right) + (* left right)) (else (die (format "Unknown bin op ~A" op)))))) (else (die (format "Unknown expr type ~A" expr))))) (define (interpret expr) - ; TODO: handle errors! (evaluate expr)) )