MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | Procedural elements: |
| 2 | ==================== |
| 3 | |
| 4 | definition of terms: |
| 5 | <block> : zero or more values to be evaluated. |
| 6 | <test> : one value to be evaluated as branch or loop condition. |
| 7 | <result> : one value to be evaluated at the end of the execution of |
| 8 | the form; the value is returned. |
| 9 | <lvalue> : local variable/parameter, global variable, or an indexed |
| 10 | lvalue. |
| 11 | <expression>: one value to be evaluated. |
| 12 | <integer> : an integer constant |
| 13 | <string> : a string constant, or 0. |
| 14 | used EBNF operators: |
| 15 | { } iteration |
| 16 | [ ] option |
| 17 | | alternative |
| 18 | |
| 19 | forms: |
| 20 | ({#', <body> <result>}) |
| 21 | ({#'? { <test> <result> } [ <result> ] }) |
| 22 | ({#'?! { <test> <result> } [ <result> ] }) |
| 23 | ({#'&& { test } }) |
| 24 | ({#'|| { test } }) |
| 25 | ({#'while <test> <result> <body>...}) loop while test evaluates non-zero. |
| 26 | ({#'do <body> <test> <result>}) loop till test evaluates zero. |
| 27 | ({#'foreach <var> <expr> <body>...}) loop over all values of <expr>. |
| 28 | ({#'foreach ({ <var>...<var> }) <expr> <body>...}) |
| 29 | ({#'= { <lvalue> <value> } }) assignment |
| 30 | other assignment operators work too. |
| 31 | case_label: <integer> | <string> | #'default |
| 32 | generalized_case_label: case_label | <integer> #'.. <integer> |
| 33 | case_label_list: case_label | ({ { generalized_case_label } }) |
| 34 | case_delimiter: #', | #'break |
| 35 | ({#'switch <expression> { case_label_list <result> case_delimiter } }) |
| 36 | Evaluate expression, then evaluate the result form labeled with |
| 37 | the value equal to the value evaluated from expression. |
| 38 | If no matching label exists, the value of #'switch is 0. |
| 39 | ({#'catch, <body> [, 'nolog ] [, 'publish ], [, 'reserve, <expr> }) |
| 40 | Evaluates the <body> and catches any runtime error. If the symbol |
| 41 | 'nolog is also given, a caught error is not logged. If the |
| 42 | symbol 'publish is also given, master::runtime_error() is |
| 43 | called for the caught error. If the symbol 'reserve with a |
| 44 | following expression is given, this value is used as the |
| 45 | computing reserve. |
| 46 | |
| 47 | |
| 48 | lisp similars: |
| 49 | #', progn |
| 50 | #'? cond |
| 51 | #'&& and |
| 52 | #'|| or |
| 53 | #'while do /* but lisp has more syntactic candy here */ |
| 54 | #'= setq |
| 55 | |
| 56 | A parameter / local variable 'foo' is referenced as 'foo , a global |
| 57 | variable as ({#'foo}) . In lvalue positions (assignment), you need not |
| 58 | enclose global variable closures in arrays. |
| 59 | |
| 60 | Call by reference parameters are given with ({#'&, <lvalue>}) |
| 61 | |
| 62 | Some special efuns: |
| 63 | #'[ indexing |
| 64 | #'[< indexing from the end |
| 65 | #'negate unary - |
| 66 | |
| 67 | Unbound lambda closures |
| 68 | ======================= |
| 69 | |
| 70 | These closures are not bound to any object. They are created with the efun |
| 71 | unbound_lambda() . They cannot contain references to global variables, and |
| 72 | all lfun closures are inserted as is, since there is no native object for |
| 73 | this closure. |
| 74 | You can bind and rebind unbound lambda closures to an object with efun |
| 75 | bind_lambda() You need to bind it before it can be called. Ordinary objects |
| 76 | can obly bind to themselves, binding to other objects causes a privilege |
| 77 | violation(). |
| 78 | The point is that previous_object for calls done from inside the closure |
| 79 | will reflect the object doing bind_lambda(), and all object / uid based |
| 80 | security will also refer to this object. |
| 81 | |
| 82 | |