fisl

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

commit 4913379bc7c3cb7b84b8ae62c0415e35df4876f4 (patch)
parent 19e70c7f8db03511f343f8243233e428497acf5c
Author: Alex Karle <alex@alexkarle.com>
Date:   Wed,  9 Nov 2022 00:38:43 -0500

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!

Diffstat:
Mfisl.scm | 3+++
Minterpreter.scm | 17++++++++++++-----
Mparser.scm | 4+++-
3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/fisl.scm b/fisl.scm @@ -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))) diff --git a/interpreter.scm b/interpreter.scm @@ -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) diff --git a/parser.scm b/parser.scm @@ -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))