Allow hex string literals in Yul.

This commit is contained in:
chriseth 2021-03-25 17:00:05 +01:00
parent 6d6112a81b
commit f04adde664
18 changed files with 64 additions and 12 deletions

View File

@ -1,6 +1,7 @@
### 0.8.4 (unreleased) ### 0.8.4 (unreleased)
Language Features: Language Features:
* Assembly / Yul: Allow hex string literals.
* Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name. * Possibility to use ``bytes.concat`` with variable number of ``bytes`` and ``bytesNN`` arguments which behaves as a restricted version of `abi.encodePacked` with a more descriptive name.
* Support custom errors via the ``error`` keyword and introduce the ``revert`` statement. * Support custom errors via the ``error`` keyword and introduce the ``revert`` statement.

View File

@ -564,5 +564,5 @@ yulPath: YulIdentifier (YulPeriod YulIdentifier)*;
*/ */
yulFunctionCall: (YulIdentifier | YulEVMBuiltin) YulLParen (yulExpression (YulComma yulExpression)*)? YulRParen; yulFunctionCall: (YulIdentifier | YulEVMBuiltin) YulLParen (yulExpression (YulComma yulExpression)*)? YulRParen;
yulBoolean: YulTrue | YulFalse; yulBoolean: YulTrue | YulFalse;
yulLiteral: YulDecimalNumber | YulStringLiteral | YulHexNumber | yulBoolean; yulLiteral: YulDecimalNumber | YulStringLiteral | YulHexNumber | yulBoolean | YulHexStringLiteral;
yulExpression: yulPath | yulFunctionCall | yulLiteral; yulExpression: yulPath | yulFunctionCall | yulLiteral;

View File

@ -263,6 +263,7 @@ YulLeave: 'leave';
YulLet: 'let'; YulLet: 'let';
YulSwitch: 'switch'; YulSwitch: 'switch';
YulTrue: 'true'; YulTrue: 'true';
YulHex: 'hex';
/** /**
* Builtin functions in the EVM Yul dialect. * Builtin functions in the EVM Yul dialect.
@ -314,7 +315,7 @@ YulDecimalNumber: '0' | ([1-9] [0-9]*);
YulStringLiteral: YulStringLiteral:
'"' DoubleQuotedStringCharacter* '"' '"' DoubleQuotedStringCharacter* '"'
| '\'' SingleQuotedStringCharacter* '\''; | '\'' SingleQuotedStringCharacter* '\'';
YulHexStringLiteral: HexString;
YulWS: [ \t\r\n\u000C]+ -> skip ; YulWS: [ \t\r\n\u000C]+ -> skip ;
YulCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ; YulCOMMENT: '/*' .*? '*/' -> channel(HIDDEN) ;

View File

@ -174,7 +174,10 @@ whitespace, i.e. there is no terminating ``;`` or newline required.
Literals Literals
-------- --------
You can use integer constants in decimal or hexadecimal notation. As literals, you can use integer constants in decimal or hexadecimal notation
or strings as ASCII (`"abc"`) or HEX strings (`hex"616263"`) of up to
32 bytes length.
When compiling for the EVM, this will be translated into an When compiling for the EVM, this will be translated into an
appropriate ``PUSHi`` instruction. In the following example, appropriate ``PUSHi`` instruction. In the following example,
``3`` and ``2`` are added resulting in 5 and then the ``3`` and ``2`` are added resulting in 5 and then the

View File

@ -285,6 +285,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
return identifier; return identifier;
} }
case Token::StringLiteral: case Token::StringLiteral:
case Token::HexStringLiteral:
case Token::Number: case Token::Number:
case Token::TrueLiteral: case Token::TrueLiteral:
case Token::FalseLiteral: case Token::FalseLiteral:
@ -293,6 +294,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
switch (currentToken()) switch (currentToken())
{ {
case Token::StringLiteral: case Token::StringLiteral:
case Token::HexStringLiteral:
kind = LiteralKind::String; kind = LiteralKind::String;
break; break;
case Token::Number: case Token::Number:
@ -324,9 +326,6 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
return literal; return literal;
} }
case Token::HexStringLiteral:
fatalParserError(3772_error, "Hex literals are not valid in this context.");
break;
case Token::Illegal: case Token::Illegal:
fatalParserError(1465_error, "Illegal token: " + to_string(m_scanner->currentError())); fatalParserError(1465_error, "Illegal token: " + to_string(m_scanner->currentError()));
break; break;

View File

@ -6,4 +6,3 @@ contract C {
} }
} }
// ---- // ----
// ParserError 3772: (72-81): Hex literals are not valid in this context.

View File

@ -6,4 +6,3 @@ contract C {
} }
} }
// ---- // ----
// ParserError 3772: (67-76): Hex literals are not valid in this context.

View File

@ -8,4 +8,3 @@ contract C {
} }
} }
// ---- // ----
// ParserError 3772: (92-99): Hex literals are not valid in this context.

View File

@ -0,0 +1,9 @@
contract C {
function f() public pure {
assembly {
let x := hex"12__34";
}
}
}
// ----
// ParserError 1465: (84-92): Illegal token: Invalid use of number separator '_'.

View File

@ -0,0 +1,9 @@
contract C {
function f() public pure {
assembly {
let x := hex"abxy";
}
}
}
// ----
// ParserError 1465: (84-90): Illegal token: Expected even number of hex-nibbles.

View File

@ -0,0 +1,5 @@
function g() pure {
assembly { let hex := 1 }
}
// ----
// ParserError 2314: (39-42): Expected identifier but got 'ILLEGAL'

View File

@ -0,0 +1,12 @@
{
let x := hex"112233445566778899aabbccddeeff6677889900"
let y := hex"1234_abcd"
sstore(0, x)
sstore(1, y)
}
// ----
// Trace:
// Memory dump:
// Storage dump:
// 0000000000000000000000000000000000000000000000000000000000000000: 112233445566778899aabbccddeeff6677889900000000000000000000000000
// 0000000000000000000000000000000000000000000000000000000000000001: 1234abcd00000000000000000000000000000000000000000000000000000000

View File

@ -2,4 +2,3 @@
let x := hex"0011" let x := hex"0011"
} }
// ---- // ----
// ParserError 3772: (15-24): Hex literals are not valid in this context.

View File

@ -0,0 +1,5 @@
{
let x := hex"00110011001100110011001100110011001100110011001100110011001100110011001100110011"
}
// ----
// TypeError 3069: (15-100): String literal too long (40 > 32)

View File

@ -2,4 +2,3 @@
pop(hex"2233") pop(hex"2233")
} }
// ---- // ----
// ParserError 3772: (10-19): Hex literals are not valid in this context.

View File

@ -0,0 +1,7 @@
{
let name := hex"abc"
}
// ====
// dialect: evm
// ----
// ParserError 1465: (18-24): Illegal token: Expected even number of hex-nibbles.

View File

@ -4,4 +4,3 @@
case hex"1122" {} case hex"1122" {}
} }
// ---- // ----
// ParserError 3772: (33-40): Hex literals are not valid in this context.

View File

@ -0,0 +1,7 @@
{
switch codesize()
case hex"00" {}
case hex"112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900" {}
}
// ----
// TypeError 3069: (53-178): String literal too long (60 > 32)