From 4913379bc7c3cb7b84b8ae62c0415e35df4876f4 Mon Sep 17 00:00:00 2001 From: Alex Karle Date: Wed, 9 Nov 2022 00:38:43 -0500 Subject: [PATCH] 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! --- fisl.scm | 3 +++ interpreter.scm | 17 ++++++++++++----- parser.scm | 4 +++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fisl.scm b/fisl.scm index e9cf8f2..1ba683d 100755 --- 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 index 5f35961..d75af85 100644 --- 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 index a37b5c8..41205a6 100644 --- 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)) -- libgit2 1.1.1