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, 13 underscores, slashes, and periods don't need to be in double quotes. 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()) 109