Doug Zongker | 37bee62 | 2009-06-08 17:35:39 -0700 | [diff] [blame] | 1 | Update scripts (from donut onwards) are written in a new little |
| 2 | scripting language ("edify") that is superficially somewhat similar to |
| 3 | the old one ("amend"). This is a brief overview of the new language. |
| 4 | |
| 5 | - The entire script is a single expression. |
| 6 | |
| 7 | - All expressions are string-valued. |
| 8 | |
| 9 | - String literals appear in double quotes. \n, \t, \", and \\ are |
| 10 | understood, as are hexadecimal escapes like \x4a. |
| 11 | |
| 12 | - String literals consisting of only letters, numbers, colons, |
Doug Zongker | 9931f7f | 2009-06-10 14:11:53 -0700 | [diff] [blame] | 13 | underscores, slashes, and periods don't need to be in double quotes. |
Doug Zongker | 37bee62 | 2009-06-08 17:35:39 -0700 | [diff] [blame] | 14 | |
| 15 | - The following words are reserved: |
| 16 | |
| 17 | if then else endif |
| 18 | |
| 19 | They have special meaning when unquoted. (In quotes, they are just |
| 20 | string literals.) |
| 21 | |
| 22 | - When used as a boolean, the empty string is "false" and all other |
| 23 | strings are "true". |
| 24 | |
| 25 | - All functions are actually macros (in the Lisp sense); the body of |
| 26 | the function can control which (if any) of the arguments are |
| 27 | evaluated. This means that functions can act as control |
| 28 | structures. |
| 29 | |
| 30 | - Operators (like "&&" and "||") are just syntactic sugar for builtin |
| 31 | functions, so they can act as control structures as well. |
| 32 | |
| 33 | - ";" is a binary operator; evaluating it just means to first evaluate |
| 34 | the left side, then the right. It can also appear after any |
| 35 | expression. |
| 36 | |
| 37 | - Comments start with "#" and run to the end of the line. |
| 38 | |
| 39 | |
| 40 | |
| 41 | Some examples: |
| 42 | |
| 43 | - There's no distinction between quoted and unquoted strings; the |
| 44 | quotes are only needed if you want characters like whitespace to |
| 45 | appear in the string. The following expressions all evaluate to the |
| 46 | same string. |
| 47 | |
| 48 | "a b" |
| 49 | a + " " + b |
| 50 | "a" + " " + "b" |
| 51 | "a\x20b" |
| 52 | a + "\x20b" |
| 53 | concat(a, " ", "b") |
| 54 | "concat"(a, " ", "b") |
| 55 | |
| 56 | As shown in the last example, function names are just strings, |
| 57 | too. They must be string *literals*, however. This is not legal: |
| 58 | |
| 59 | ("con" + "cat")(a, " ", b) # syntax error! |
| 60 | |
| 61 | |
| 62 | - The ifelse() builtin takes three arguments: it evaluates exactly |
| 63 | one of the second and third, depending on whether the first one is |
| 64 | true. There is also some syntactic sugar to make expressions that |
| 65 | look like if/else statements: |
| 66 | |
| 67 | # these are all equivalent |
| 68 | ifelse(something(), "yes", "no") |
| 69 | if something() then yes else no endif |
| 70 | if something() then "yes" else "no" endif |
| 71 | |
| 72 | The else part is optional. |
| 73 | |
| 74 | if something() then "yes" endif # if something() is false, |
| 75 | # evaluates to false |
| 76 | |
| 77 | ifelse(condition(), "", abort()) # abort() only called if |
| 78 | # condition() is false |
| 79 | |
| 80 | The last example is equivalent to: |
| 81 | |
| 82 | assert(condition()) |
| 83 | |
| 84 | |
| 85 | - The && and || operators can be used similarly; they evaluate their |
| 86 | second argument only if it's needed to determine the truth of the |
| 87 | expression. Their value is the value of the last-evaluated |
| 88 | argument: |
| 89 | |
| 90 | file_exists("/data/system/bad") && delete("/data/system/bad") |
| 91 | |
| 92 | file_exists("/data/system/missing") || create("/data/system/missing") |
| 93 | |
| 94 | get_it() || "xxx" # returns value of get_it() if that value is |
| 95 | # true, otherwise returns "xxx" |
| 96 | |
| 97 | |
| 98 | - The purpose of ";" is to simulate imperative statements, of course, |
| 99 | but the operator can be used anywhere. Its value is the value of |
| 100 | its right side: |
| 101 | |
| 102 | concat(a;b;c, d, e;f) # evaluates to "cdf" |
| 103 | |
| 104 | A more useful example might be something like: |
| 105 | |
| 106 | ifelse(condition(), |
| 107 | (first_step(); second_step();), # second ; is optional |
| 108 | alternative_procedure()) |