Skip to content

Commit 6e689c9

Browse files
committed
Support for the Yul language
1 parent ec2ff6c commit 6e689c9

7 files changed

Lines changed: 169 additions & 2 deletions

File tree

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,26 @@ The following is the default configuration internally used by this plugin.
109109
"plugins": ["prettier-plugin-solidity"],
110110
"overrides": [
111111
{
112-
"files": "*.sol",
112+
"files": ["*.sol", "*.yul"],
113113
"options": {
114-
"parser": "slang",
115114
"printWidth": 80,
116115
"tabWidth": 4,
117116
"useTabs": false,
118117
"singleQuote": false,
119118
"bracketSpacing": false,
120119
}
120+
},
121+
{
122+
"files": "*.sol",
123+
"options": {
124+
"parser": "slang"
125+
}
126+
},
127+
{
128+
"files": "*.yul",
129+
"options": {
130+
"parser": "slang-yul"
131+
}
121132
}
122133
]
123134
}

src/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import options from './options.js';
66
import antlrParse from './parser.js';
77
import antlrPrint from './printer.js';
88
import slangParse from './slangSolidityParser.js';
9+
import yulParse from './slangYulParser.js';
910
import slangPrint from './slangPrinter.js';
1011
import { isBlockComment, isComment } from './slang-utils/is-comment.js';
1112
import { locEnd, locStart } from './slang-utils/loc.js';
@@ -19,6 +20,7 @@ import type {
1920
import type { AstNode } from './slang-nodes/types.d.ts';
2021

2122
const slangParserId = 'slang';
23+
const slangYulParserId = 'slang-yul';
2224
const antlrParserId = 'antlr';
2325
const slangAstId = 'slang-ast';
2426
const antlrAstId = 'antlr-ast';
@@ -34,6 +36,15 @@ const languages: SupportLanguage[] = [
3436
extensions: ['.sol'],
3537
parsers: [slangParserId, antlrParserId],
3638
vscodeLanguageIds: ['solidity']
39+
},
40+
{
41+
linguistLanguageId: 237469033,
42+
name: 'Yul',
43+
aceMode: 'text',
44+
tmScope: 'source.yul',
45+
extensions: ['.yul'],
46+
parsers: [slangYulParserId],
47+
vscodeLanguageIds: ['yul']
3748
}
3849
];
3950

@@ -45,9 +56,16 @@ const slangParser: Parser<AstNode> = {
4556
locStart,
4657
locEnd
4758
};
59+
const yulParser: Parser<AstNode> = {
60+
astFormat: slangAstId,
61+
parse: yulParse,
62+
locStart,
63+
locEnd
64+
};
4865

4966
const parsers = {
5067
[slangParserId]: slangParser,
68+
[slangYulParserId]: yulParser,
5169
[antlrParserId]: antlrParser
5270
};
5371

src/slangYulParser.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// https://prettier.io/docs/en/plugins.html#parsers
2+
import { YulBlock as SlangYulBlock } from '@nomicfoundation/slang/ast';
3+
import { NonterminalKind } from '@nomicfoundation/slang/cst';
4+
import { Parser } from '@nomicfoundation/slang/parser';
5+
import { LanguageFacts } from '@nomicfoundation/slang/utils';
6+
import { coerce } from 'semver';
7+
import { clearOffsets } from './slang-utils/metadata.js';
8+
import { YulBlock } from './slang-nodes/YulBlock.js';
9+
10+
import type { ParserOptions } from 'prettier';
11+
import type { AstNode } from './slang-nodes/types.d.ts';
12+
13+
export default function parse(
14+
text: string,
15+
options: ParserOptions<AstNode>
16+
): AstNode {
17+
// const [parser, parseOutput] = createParser(text, options);
18+
const compiler = coerce(options.compiler);
19+
const supportedVersions = LanguageFacts.allVersions();
20+
21+
const parser = Parser.create(
22+
compiler && supportedVersions.includes(compiler.version)
23+
? compiler.version
24+
: supportedVersions[supportedVersions.length - 1]
25+
);
26+
27+
const parseOutput = parser.parseNonterminal(NonterminalKind.YulBlock, text);
28+
29+
if (parseOutput.isValid()) {
30+
// We update the compiler version by the inferred one.
31+
options.compiler = parser.languageVersion;
32+
const parsed = new YulBlock(
33+
new SlangYulBlock(parseOutput.tree.asNonterminalNode()),
34+
options
35+
);
36+
clearOffsets();
37+
return parsed;
38+
}
39+
throw new Error(parseOutput.errors()[0].message);
40+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`example1.yul format 1`] = `
4+
====================================options=====================================
5+
parsers: ["slang-yul"]
6+
printWidth: 80
7+
| printWidth
8+
=====================================input======================================
9+
{
10+
function power(base, exponent) -> result
11+
{
12+
switch exponent
13+
case 0 { result := 1 }
14+
case 1 { result := base }
15+
default
16+
{
17+
result := power(mul(base, base), div(exponent, 2))
18+
switch mod(exponent, 2)
19+
case 1 { result := mul(base, result) }
20+
}
21+
}
22+
}
23+
=====================================output=====================================
24+
{
25+
function power(base, exponent) -> result {
26+
switch exponent
27+
case 0 {
28+
result := 1
29+
}
30+
case 1 {
31+
result := base
32+
}
33+
default {
34+
result := power(mul(base, base), div(exponent, 2))
35+
switch mod(exponent, 2)
36+
case 1 {
37+
result := mul(base, result)
38+
}
39+
}
40+
}
41+
}
42+
================================================================================
43+
`;
44+
45+
exports[`example2.yul format 1`] = `
46+
====================================options=====================================
47+
parsers: ["slang-yul"]
48+
printWidth: 80
49+
| printWidth
50+
=====================================input======================================
51+
{
52+
function power(base, exponent) -> result
53+
{
54+
result := 1 for { let i := 0 } lt(i, exponent) { i := add(i, 1) }
55+
{
56+
result := mul(result, base)
57+
}
58+
}
59+
}
60+
=====================================output=====================================
61+
{
62+
function power(base, exponent) -> result {
63+
result := 1
64+
for {
65+
let i := 0
66+
} lt(i, exponent) {
67+
i := add(i, 1)
68+
} {
69+
result := mul(result, base)
70+
}
71+
}
72+
}
73+
================================================================================
74+
`;

tests/format/Yul/example1.yul

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
function power(base, exponent) -> result
3+
{
4+
switch exponent
5+
case 0 { result := 1 }
6+
case 1 { result := base }
7+
default
8+
{
9+
result := power(mul(base, base), div(exponent, 2))
10+
switch mod(exponent, 2)
11+
case 1 { result := mul(base, result) }
12+
}
13+
}
14+
}

tests/format/Yul/example2.yul

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
function power(base, exponent) -> result
3+
{
4+
result := 1 for { let i := 0 } lt(i, exponent) { i := add(i, 1) }
5+
{
6+
result := mul(result, base)
7+
}
8+
}
9+
}

tests/format/Yul/format.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
runFormatTest(import.meta, ['slang-yul']);

0 commit comments

Comments
 (0)