~akarle/fisl

4913379bc7c3cb7b84b8ae62c0415e35df4876f4 — Alex Karle 1 year, 5 months ago 19e70c7
repl: Print expr-stmts and drop need for ';'

In the repl, we can drop the requirements on using ';' for most
statements.

By allowing execute to evaluate and print expr-statemtents we go from
this:

> var x = 1;
> print x = 2;
2

to

> var x = 1;
> x = 2
2
> x
2

Nice!
3 files changed, 18 insertions(+), 6 deletions(-)

M fisl.scm
M interpreter.scm
M parser.scm
M fisl.scm => fisl.scm +3 -0
@@ 12,6 12,8 @@
(include "parser.scm")
(include "interpreter.scm")

(define in-repl #f)

(define (run code)
  (let ((tokens (scan code)))
    (if tokens


@@ 49,6 51,7 @@
  (let ((argc (length args)))
    (cond
      ((eq? argc 0)
       (set! in-repl #t)
       (thread-start! (lambda () (run-prompt) (exit 0)))
       (nrepl 1234))
      ((eq? argc 1) (run-file (car args)))

M interpreter.scm => interpreter.scm +12 -5
@@ 94,15 94,18 @@
        (else (runtime-err! (format "Unknown bin op ~A" op))))))
   (else (runtime-err! (format "Unknown expr type ~A" expr)))))

(define (lox-print val)
  (print (cond
           ((null? val) "nil")
           ((eq? val #f) "false")
           ((eq? val #t) "true")
           (else val))))

(define (execute stmt)
  (cond
   ((print-stmt? stmt)
    (let ((res (evaluate (print-stmt-value stmt))))
      (print (cond
               ((null? res) "nil")
               ((eq? res #f) "false")
               ((eq? res #t) "true")
               (else res)))
      (lox-print res)
      '()))
   ((var-stmt? stmt)
    (let ((value


@@ 111,6 114,10 @@
              (evaluate (var-stmt-init stmt)))))
      (hash-table-set! global-env (token-lexeme (var-stmt-name stmt)) value))
    '())
   ((expr-stmt? stmt)
    (let ((res (evaluate (expr-stmt-value stmt))))
      (if in-repl (lox-print res))
      '()))
   (else (runtime-err! (format "Unknown stmt ~A" stmt)))))

(define (interpret stmts)

M parser.scm => parser.scm +3 -1
@@ 87,7 87,9 @@
  (let-values (((expr toks) (parse-expression '() tokens)))
    (if (top-type? toks '(SEMICOLON))
      (values (maker expr) (cdr toks))
      (parse-err! (car toks) "expected ;"))))
      (if in-repl
        (values (maker expr) toks)
        (parse-err! (car toks) "expected ;")))))

(define (parse-print-statement tokens)
  (parse-generic-stmt tokens make-print-stmt))