diff options
author | chriseth <chris@ethereum.org> | 2017-11-27 22:02:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-27 22:02:46 +0800 |
commit | a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a (patch) | |
tree | d17e5ab7a2c9cd5ffacba728851e6c127182fbe0 /docs | |
parent | a7136dbc16ba7e0cf8a7d6097d50cc40c1248914 (diff) | |
parent | 1d91b65b726d4757b866124d75834f28a9bc9eb9 (diff) | |
download | dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar.gz dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar.bz2 dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar.lz dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar.xz dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.tar.zst dexon-solidity-a1f59cbb17d29ca5f92fa1cc20d17f47026ade5a.zip |
Merge pull request #3220 from ethereum/IuliaIf
If statement for Iulia / Inline Assembly
Diffstat (limited to 'docs')
-rw-r--r-- | docs/assembly.rst | 24 | ||||
-rw-r--r-- | docs/julia.rst | 12 |
2 files changed, 31 insertions, 5 deletions
diff --git a/docs/assembly.rst b/docs/assembly.rst index 00bfb388..c233985b 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -26,6 +26,7 @@ arising when writing manual assembly by the following features: * access to external variables: ``function f(uint x) { assembly { x := sub(x, 1) } }`` * labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))`` * loops: ``for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }`` +* if statements: ``if slt(x, 0) { x := sub(0, x) }`` * switch statements: ``switch x case 0 { y := mul(x, 2) } default { y := 0 }`` * function calls: ``function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } }`` @@ -400,7 +401,7 @@ Labels Another problem in EVM assembly is that ``jump`` and ``jumpi`` use absolute addresses which can change easily. Solidity inline assembly provides labels to make the use of jumps easier. Note that labels are a low-level feature and it is possible to write -efficient assembly without labels, just using assembly functions, loops and switch instructions +efficient assembly without labels, just using assembly functions, loops, if and switch instructions (see below). The following code computes an element in the Fibonacci series. .. code:: @@ -523,6 +524,21 @@ is performed by replacing the variable's value on the stack by the new value. =: v // instruction style assignment, puts the result of sload(10) into v } +If +-- + +The if statement can be used for conditionally executing code. +There is no "else" part, consider using "switch" (see below) if +you need multiple alternatives. + +.. code:: + + { + if eq(value, 0) { revert(0, 0) } + } + +The curly braces for the body are required. + Switch ------ @@ -622,7 +638,7 @@ Things to Avoid --------------- Inline assembly might have a quite high-level look, but it actually is extremely -low-level. Function calls, loops and switches are converted by simple +low-level. Function calls, loops, ifs and switches are converted by simple rewriting rules and after that, the only thing the assembler does for you is re-arranging functional-style opcodes, managing jump labels, counting stack height for variable access and removing stack slots for assembly-local variables when the end @@ -669,7 +685,7 @@ for the Solidity compiler. In this form, it tries to achieve several goals: 3. Control flow should be easy to detect to help in formal verification and optimization. In order to achieve the first and last goal, assembly provides high-level constructs -like ``for`` loops, ``switch`` statements and function calls. It should be possible +like ``for`` loops, ``if`` and ``switch`` statements and function calls. It should be possible to write assembly programs that do not make use of explicit ``SWAP``, ``DUP``, ``JUMP`` and ``JUMPI`` statements, because the first two obfuscate the data flow and the last two obfuscate control flow. Furthermore, functional statements of @@ -875,6 +891,7 @@ Grammar:: FunctionalAssemblyAssignment | AssemblyAssignment | LabelDefinition | + AssemblyIf | AssemblySwitch | AssemblyFunctionDefinition | AssemblyFor | @@ -891,6 +908,7 @@ Grammar:: IdentifierList = Identifier ( ',' Identifier)* AssemblyAssignment = '=:' Identifier LabelDefinition = Identifier ':' + AssemblyIf = 'if' FunctionalAssemblyExpression AssemblyBlock AssemblySwitch = 'switch' FunctionalAssemblyExpression AssemblyCase* ( 'default' AssemblyBlock )? AssemblyCase = 'case' FunctionalAssemblyExpression AssemblyBlock diff --git a/docs/julia.rst b/docs/julia.rst index cf798363..309e6b36 100644 --- a/docs/julia.rst +++ b/docs/julia.rst @@ -15,7 +15,7 @@ future versions of the Solidity compiler will even use JULIA as intermediate language. It should also be easy to build high-level optimizer stages for JULIA. The core components of JULIA are functions, blocks, variables, literals, -for-loops, switch-statements, expressions and assignments to variables. +for-loops, if-statements, switch-statements, expressions and assignments to variables. JULIA is typed, both variables and literals must specify the type with postfix notation. The supported types are ``bool``, ``u8``, ``s8``, ``u32``, ``s32``, @@ -88,6 +88,8 @@ Grammar:: IdentifierList ':=' Expression Expression = FunctionCall | Identifier | Literal + If = + 'if' Expression Block Switch = 'switch' Expression Case* ( 'default' Block )? Case = @@ -248,8 +250,14 @@ We will use a destructuring notation for the AST nodes. G, L, break E(G, L, continue: BreakContinue) = G, L, continue + E(G, L, <if condition body>: If) = + let G0, L0, v = E(G, L, condition) + if v is true: + E(G0, L0, body) + else: + G0, L0, regular E(G, L, <switch condition case l1:t1 st1 ... case ln:tn stn>: Switch) = - E(G, L, switch condition case l1:t1 st1 ... case ln:tn stn default {}) = + E(G, L, switch condition case l1:t1 st1 ... case ln:tn stn default {}) E(G, L, <switch condition case l1:t1 st1 ... case ln:tn stn default st'>: Switch) = let G0, L0, v = E(G, L, condition) // i = 1 .. n |