mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Describe Julia.
This commit is contained in:
parent
4e0723ce27
commit
243002e5f3
@ -1,18 +1,116 @@
|
|||||||
#################
|
#################################################
|
||||||
Solidity Assembly
|
Joyfully Universal Language for (Inline) Assembly
|
||||||
#################
|
#################################################
|
||||||
|
|
||||||
|
.. _julia:
|
||||||
|
|
||||||
.. index:: ! assembly, ! asm, ! evmasm
|
.. index:: ! assembly, ! asm, ! evmasm
|
||||||
|
|
||||||
Solidity defines an assembly language that can also be used without Solidity.
|
Julia is an intermediate language that can compile to various different backends
|
||||||
This assembly language can also be used as "inline assembly" inside Solidity
|
(EVM 1.0, EVM 1.5 and eWASM are planned).
|
||||||
source code. We start with describing how to use inline assembly and how it
|
Because of that, it is designed to be as featureless as possible.
|
||||||
differs from standalone assembly and then specify assembly itself.
|
It can already be used for "inline assembly" inside Solidity and
|
||||||
|
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.
|
||||||
|
|
||||||
.. note::
|
The core components of Julia are functions, blocks, variables, literals,
|
||||||
TODO: Write about how scoping rules of inline assembly are a bit different
|
for-loops, switch-statements, expressions and assignments to variables.
|
||||||
and the complications that arise when for example using internal functions
|
|
||||||
of libraries. Furthermore, write about the symbols defined by the compiler.
|
Julia in itself does not even provide operators. If the EVM is targeted,
|
||||||
|
opcodes will be available as built-in functions, but they can be reimplemented
|
||||||
|
if the backend changes.
|
||||||
|
|
||||||
|
The following example program assumes that the EVM opcodes ``mul``, ``div``
|
||||||
|
and ``mod`` are available either natively or as functions and computes exponentiation.
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
{
|
||||||
|
function power(base, exponent) -> (result)
|
||||||
|
{
|
||||||
|
switch exponent
|
||||||
|
0: { result := 1 }
|
||||||
|
1: { result := base }
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
result := power(mul(base, base), div(exponent, 2))
|
||||||
|
switch mod(exponent, 2)
|
||||||
|
1: { result := mul(base, result) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It is also possible to implement the same function using a for-loop
|
||||||
|
instead of recursion. Here, we need the EVM opcodes ``lt`` (less-than)
|
||||||
|
and ``add`` to be available.
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
{
|
||||||
|
function power(base, exponent) -> (result)
|
||||||
|
{
|
||||||
|
result := 1
|
||||||
|
for { let i := 0 } lt(i, exponent) { i := add(i, 1) }
|
||||||
|
{
|
||||||
|
result := mul(result, base)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Specification of Julia
|
||||||
|
======================
|
||||||
|
|
||||||
|
Grammar::
|
||||||
|
|
||||||
|
Block = '{' Statement* '}'
|
||||||
|
Statement =
|
||||||
|
Block |
|
||||||
|
FunctionDefinition |
|
||||||
|
VariableDeclaration |
|
||||||
|
Assignment |
|
||||||
|
Expression |
|
||||||
|
Switch |
|
||||||
|
ForLoop |
|
||||||
|
'break' | 'continue'
|
||||||
|
SubAssembly
|
||||||
|
FunctionDefinition =
|
||||||
|
'function' Identifier '(' IdentifierList? ')'
|
||||||
|
( '->' '(' IdentifierList ')' )? Block
|
||||||
|
VariableDeclaration =
|
||||||
|
'let' IdentifierOrList ':=' Expression
|
||||||
|
Assignment =
|
||||||
|
IdentifierOrList ':=' Expression
|
||||||
|
Expression =
|
||||||
|
Identifier | Literal | FunctionCall
|
||||||
|
Switch =
|
||||||
|
'switch' Expression Case* ( 'default' ':' Block )?
|
||||||
|
Case =
|
||||||
|
'case' Expression ':' Block
|
||||||
|
ForLoop =
|
||||||
|
'for' Block Expression Block Block
|
||||||
|
SubAssembly =
|
||||||
|
'assembly' Identifier Block
|
||||||
|
FunctionCall =
|
||||||
|
Identifier '(' ( AssemblyItem ( ',' AssemblyItem )* )? ')'
|
||||||
|
IdentifierOrList = Identifier | '(' IdentifierList ')'
|
||||||
|
Identifier = [a-zA-Z_$] [a-zA-Z_0-9]*
|
||||||
|
IdentifierList = Identifier ( ',' Identifier)*
|
||||||
|
Literal =
|
||||||
|
NumberLiteral | StringLiteral | HexLiteral
|
||||||
|
NumberLiteral = HexNumber | DecimalNumber
|
||||||
|
HexLiteral = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'')
|
||||||
|
StringLiteral = '"' ([^"\r\n\\] | '\\' .)* '"'
|
||||||
|
HexNumber = '0x' [0-9a-fA-F]+
|
||||||
|
DecimalNumber = [0-9]+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| 'dataSize' '(' Identifier ')' |
|
||||||
|
LinkerSymbol |
|
||||||
|
'bytecodeSize' |
|
||||||
|
|
||||||
|
Restriction for Expression: Functions can only return single item,
|
||||||
|
top level has to return nothing.
|
||||||
|
Restriction for VariableDeclaration and Assignment: Number of elements left and right needs to be the same
|
||||||
|
continue and break only in for loop
|
||||||
|
|
||||||
.. _inline-assembly:
|
.. _inline-assembly:
|
||||||
|
|
||||||
@ -41,6 +139,11 @@ We now want to describe the inline assembly language in detail.
|
|||||||
at a low level. This discards several important safety
|
at a low level. This discards several important safety
|
||||||
features of Solidity.
|
features of Solidity.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
TODO: Write about how scoping rules of inline assembly are a bit different
|
||||||
|
and the complications that arise when for example using internal functions
|
||||||
|
of libraries. Furthermore, write about the symbols defined by the compiler.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user