From 535e853d369f49f8b45e35cd21dd2f7495445429 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 14 Dec 2011 12:14:56 -0800 Subject: * eval.c (op_dohash): Esbatlish anonymous block. * txr.1: Finished documenting special operators. --- ChangeLog | 6 +++ eval.c | 8 +++- txr.1 | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 167 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef0a08f4..c5b2356d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-12-14 Kaz Kylheku + + * eval.c (op_dohash): Esbatlish anonymous block. + + * txr.1: Finished documenting special operators. + 2011-12-14 Kaz Kylheku * genman.txr: Fix empty NAME section. diff --git a/eval.c b/eval.c index 6ba918ed..e4931400 100644 --- a/eval.c +++ b/eval.c @@ -647,13 +647,19 @@ static val op_dohash(val form, val env) val new_env = make_env(cons(keyvar, cons(valvar, nil)), nil, env); val cell; + uw_block_begin (nil, result); + while ((cell = hash_next(&iter)) != nil) { *cdr_l(keyvar) = car(cell); *cdr_l(valvar) = cdr(cell); eval_progn(body, new_env, form); } - return eval(resform, new_env, form); + result = eval(resform, new_env, form); + + uw_block_end; + + return result; } static val op_unwind_protect(val form, val env) diff --git a/txr.1 b/txr.1 index 5aad3b1b..d9cf29c8 100644 --- a/txr.1 +++ b/txr.1 @@ -4687,15 +4687,24 @@ Currently, these forms are recognized as places: (gethash ) + (vecref ) + A place denotes a variable. If the variable does not exist, it is an -error. The (car
) and (cdr ) places denote the corresponding slots +error. + +The (car ) and (cdr ) places denote the corresponding slots of a cons cell. The form must be an expression which evaluates to a -cons. The gethash place denotes a value stored in a hash table. +cons. + +The gethash place denotes a value stored in a hash table. The form must evaluate to a hash table. If the place does not exist in the hash table under the given key, then the destructive operation will create it. In that case, the form is evaluated to determine the initial value of the place. Otherwise it is ignored. +The vecref place denotes a vector element, allowing vector elements +to be treated as assignment places. + .SS Operators for and for* .TP @@ -4737,12 +4746,154 @@ allowing the return operator to be used to terminate at any point. .SS Operator dohash +.TP +Syntax: + +(dohash ( []) + *) + +.TP +Description: + +The dohash operator iterates over a hash table. The expression must +evaluate to an object of hash table type. The and +arguents must be symbols suitable for use as variable names. +Bindings are established for these variables over the scope of the +-s and the optional result form. + +For each element in the hash table, the and +variables are set to the key and value of that entry, respectively, +and each , if there are any, is evaluated. + +When all of the entries of the table are thus processed, the is +evaluated, and its return value becomes the return value of the dohash form. If +there is no , the return value is nil. + +The and -s are in the scope of an implicit anonymous +block, which means that it is possible to terminate the execution of +dohash early using (return) or (return ). + .SS Operator unwind-protect +.TP +Syntax: + +(unwind-protect *) + +.TP +Description: + +The unwind-protect operator evaluates in such a way that no +matter how the execution of terminates, the -s +will be executed. + +The cleanup forms, however, are not protected. If a cleanup form terminates via +some non-local jump, the subsequent cleanup forms are not evaluated. + +Cleanup forms themselves can "hijack" a non-local control transfer such +as an exception. If a cleanup form is evaluated during the processing of +a dynamic control transfer such as an exception, and that cleanup form +initiats its own dynamic control transfer, the original control transfer +is aborted and replaced with the new one. + +.TP +Example: + + (block foo + (unwind-protect + (progn (return-from foo 42) + (format t "not reached!\en")) + (format t "cleanup!\n"))) + +In this example, the protected progn form terminates by returning from +block foo. Therefore the form does not complete and so the +output "not reached!" is not produced. However, the cleanup form +excecutes, producing the output "cleanup!". + + .SS Operator block +.TP +Syntax: + +(block *} + +.TP +Description: + +The block operator introduces a named block around the execution of +some forms. The argument must be a symbol. Since a block name is not +a variable binding, keyword symbols are permitted, and so are the symbols +t and nil. A block named by the symbol nil is slighlty special: it is +understood to be an anonymous block. + +Blocks in TXR Lisp have dynamic scope. This means that the following +situation is allowed: + + (defun func () (return-from foo 42)) + (block foo (func)) + +The function can return from the foo block even though the foo block +does not lexically surround foo. + +Thus blocks in TXR Lisp provide dynamic non-local returns, as well +as returns out of lexical nesting. + +.TP +Dialect Note: + +In Common Lisp, blocks are lexical. A separate mechanism consisting of +catch and throw operators performs non-local transfer based on symbols. +The TXR Lisp example: + + (defun func () (return-from foo 42)) + (block foo (func)) + +is not allowed in Common Lisp, but can be transliterated to: + + (defun func () (throw 'foo 42)) + (catch 'foo (func)) + +Note that foo is quoted in CL. This underscores the dynamic nature of +the construct. THROW itself is a function and not an operator. + .SS Operators return, return-from +.TP +Syntax: + +(return []) + +(return-from []) + +.TP +Description: + +The return operator must be dynamically enclosed within an anonymous +block (a block named by the symbol nil). It immediately terminates the +evaluation of the innermost anonyous block which encloses it, causing +it to return the specified value. If the value is omitted, the anonymous +block returns nil. + +The return-from operator must be dynamically enclosed within a named block +whose name matches the argument. It immediately terminates the +evaluation of the innermost such block, causing it to return the specified +value. If the value is omitted, that block returns nil. + +.TP +Example: + + (block foo + (let ((a "abc\n") + (b "def\n")) + (pprint a *stdout*) + (return-from foo 42) + (pprint b *stdout*))) + +Here, the output produced is "abc". The value of b is not printed +because the return-from terminates block foo, and so the second pprint +form is not evaluated. + .SS Lisp Functions and Variables When the first element of a compound form is a symbol denoting a function, @@ -4797,7 +4948,7 @@ The following are Lisp functions and variables built-in to TXR. .SS Functions reverse, nreverse -.SS Function ldfiff +.SS Function ldiff .SS Function flatten -- cgit v1.2.3