ScratchData LogoScratchData
Back to mlcreater's profile

Interpreter-v1 (Lisp/Scheme-like language)

MLmlcreater•Created January 13, 2025
Interpreter-v1 (Lisp/Scheme-like language)
0
0
3 views
View on Scratch

Description

(with lexical scope, proper tail recursion, and call/cc!) How to use: [Bind] defines variables; in particular, it allows you to store computation results [Eval] asks for an expression and evaluates it; when evaluation finishes, the result is in the form of a pointer, which you most likely want to give to "Write" and/or "Bind". [Stop] interrupts evaluation in case of an infinite loop [Write] displays memory contents in s-expression format [GC] runs garbage collection [Setup] = green-flag, resets [Show/Hide] shows/hides memory stop-sign stops speech bubbles Read-syntax forms: a : a symbol, for now made of letters, digits, and !#$%&*+-/:<=>?^_~ "abc" : a string, supporting escapes \" and \\ (x . y) : a pair of subforms () : the symbol nil (x) == (x . ()) == (x . nil) : a list (x y) == (x . (y)) == (x . (y . nil)) : a list (x y z) == (x . (y z)) == (x . (y . (z . nil))) : a list ... (x y . z) == (x . (y . z)) == (x . (y . z)) (w x y . z) == (w . (x y . z)) == (w . (x . (y . z))) ... 'x : the list (quote x) == (quote . (x . nil)) Language syntax forms: a a symbol is a variable reference "abc" strings evaluate to themselves (lambda (a) x) (lambda (a b ...) x) (lambda a x) (lambda (a ... b . c) x) a function is specified with a list containing the symbol lambda, an argument list, and a body consisting of one expression, which may use the variables 'x (quote x) to include a literal form without evaluating it, quote it (if x y z) this first evaluates the condition expression, x; if the condition is true (anything but the symbol f), it evaluates the second expression, y; if the condition is false (the symbol f), it evaluates the third expression, z (f) (f x) (f x y ...) a list starting with anything except if, quote, or lambda is a function application; each list item is evaluated--the first, f, should evaluate to a function; and then any items after the first are passed as arguments to the first Built-in functions: (apply fn args) calls the function fn; args is a list containing the arguments to be passed to fn (call/cc proc) "call with current continuation" calls the function proc; fn must have one parameter; the argument passed to proc is a function of one parameter, the "continuation", which when called returns its argument "out of" this call to call/cc (car a) a must be a pair; car returns its first element (cdr a) a must be a pair; cdr returns its second element (cons a b) creates a pair (a . b) (eq? a b) returns the symbol t if a and b refer to the same memory location; returns the symbol f otherwise; in particular, eq? always returns t on two symbols with the same name, but does not always return t on two strings with the same content (pair? obj) returns t if obj is a pair; returns f otherwise (string? obj) returns t if obj is a string; returns f otherwise (symbol? obj) returns t if obj is a symbol; returns f otherwise Examples: => will mean "evaluates to"; to see that (if 't 'yes 'no) => yes, give (if 't 'yes 'no) to [Eval] and get a number, say, 123, then give that number to [Write} and get yes "abc" => "abc" '"abc" => "abc" 'a => a '(if x y z) => (if x y z) (if 't 'yes 'no) => yes (if "helloworld" 'yes 'no) => yes (if '() 'yes 'no) => yes (if 'f 'yes 'no) => no (car '(x . y)) => x (cdr '(x . y)) => y (cdr '(x y)) => (y) (cons 'x 'y) => (x . y) (cons 'x '(y z)) => (x y z) (pair? (x . y)) => t (pair? (x y)) => t (symbol? 'a) => t (string? "abc") => t (lambda () 'a) => {a function} ((lambda () 'a)) => a ((lambda (x) x) 'a) => a ((lambda (x y) y) 'a 'b) => b ((lambda x x) 'a 'b 'c) => (a b c) ((lambda (x . y) y) 'a 'b 'c 'd) => (b c d) (apply cons '(x y)) => (x . y) (eq? 'x 'x) => t (eq? (cons 'x 'y) (cons 'x 'y)) => f ; because each call to cons creates a new cell ((lambda (a) (eq? a a)) (cons 'x 'y)) => t (call/cc (lambda (c) (c 'a))) => a ; (c 'a) means, return the result of 'a "out of" call/cc (call/cc (lambda (c) 'a)) => a ; returning normally out of proc is possible too (call/cc string?) => f ; the continuation is a function, not a string More examples: -> will mean "is stored in the variable"; to follow (cons 'x 'y) -> my-variable, give (cons 'x 'y) to [Eval] and get a number, say 123, then give that number and the name my-variable to [Bind]; to see that the binding worked, give my-variable to [Eval] and get the same number as before (cons 'x 'y) -> my-variable my-variable => (x . y) (eq? my-variable (cons 'x 'y)) => f (eq? my-variable my-variable) => t (lambda x x) -> list (list 'a 'b 'c) => (a b c) (lambda (x) (list x x x)) -> triple (triple 'a) => (a a a) (lambda (f) (f f)) -> self-apply (self-apply string?) => f (self-apply self-apply) ; an infinite loop (lambda (x) (lambda (y) (cons x y))) -> curry-cons ((curry-cons 'x) 'y) => (x . y) (lambda (f g) (lambda x (f (apply g x)))) -> compose ((compose cdr cons) 'x 'y) => y (lambda (f i o) (if (pair? i) (f f (cdr i) (cons (car i) o)) o)) -> reverse-step (lambda (l) (reverse-step reverse-step l '())) -> reverse (reverse '(x y z)) => (z y x)

Project Details

Project ID1119747201
CreatedJanuary 13, 2025
Last ModifiedJune 19, 2025
SharedJune 19, 2025
Visibilityvisible
CommentsAllowed

Remix Information

Parent ProjectView Parent
Root ProjectView Root