-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: support for basic yul types * feat: support parsing of yul-like evm opcodes * feat(syn-solidity): parse yul function calls * feat(syn-solidity): support parsing yul for loops * feat(syn-solidity): support parsing yul switch statements * feat(syn-solidity): move walrus token to own file, support parsing assign stmts * feat(syn-solidity): parse yul stmts * feat(syn-solidity): parse hex num, yul lits, + cleanup * feat(syn-solidity): support yul path + bug fixes * cleanup + parsing bug fixes * fix small nits * Update crates/syn-solidity/src/yul/type/function.rs Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * fix: correct doc link for yulAssignment * fix: expose private struct vars * fix: replace redudant YulPath enum with wrapper struct * fix: ignore tokens in fmt::Debug, convert YulAssign & YulDecl into structs * fix: replace blob import with individual imports * fix: ensure switch has atleast one case or default * fix: remove YulLit and replace with crate::Lit --------- Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
- Loading branch information
1 parent
be55894
commit 2967dd9
Showing
19 changed files
with
1,317 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
use crate::{utils::DebugPunctuated, Spanned, YulEVMBuiltIn, YulExpr, YulIdent}; | ||
|
||
use proc_macro2::Span; | ||
use std::fmt; | ||
use syn::{ | ||
parenthesized, | ||
parse::{discouraged::Speculative, Parse, ParseStream, Result}, | ||
punctuated::Punctuated, | ||
token::Paren, | ||
Token, | ||
}; | ||
|
||
/// Yul function call. | ||
/// | ||
/// Solidity Reference: | ||
/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.yulFunctionCall> | ||
#[derive(Clone)] | ||
pub struct YulFnCall { | ||
pub function_type: FnType, | ||
pub paren_token: Paren, | ||
pub arguments: Punctuated<YulExpr, Token![,]>, | ||
} | ||
|
||
impl Parse for YulFnCall { | ||
fn parse(input: ParseStream<'_>) -> Result<Self> { | ||
let content; | ||
Ok(Self { | ||
function_type: input.parse()?, | ||
paren_token: parenthesized!(content in input), | ||
arguments: content.parse_terminated(YulExpr::parse, Token![,])?, | ||
}) | ||
} | ||
} | ||
|
||
impl Spanned for YulFnCall { | ||
fn span(&self) -> Span { | ||
let span = self.function_type.span(); | ||
span.join(self.arguments.span()).unwrap_or(span) | ||
} | ||
|
||
fn set_span(&mut self, span: Span) { | ||
self.function_type.set_span(span); | ||
self.paren_token = Paren(span); | ||
self.arguments.set_span(span); | ||
} | ||
} | ||
|
||
impl fmt::Debug for YulFnCall { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_struct("YulFnCall") | ||
.field("function_type", &self.function_type) | ||
.field("arguments", DebugPunctuated::new(&self.arguments)) | ||
.finish() | ||
} | ||
} | ||
|
||
/// What type of function is called. | ||
#[derive(Clone)] | ||
pub enum FnType { | ||
/// When calling a self defined function | ||
Custom(YulIdent), | ||
|
||
/// When calling a built in evm opcode | ||
EVMOpcode(YulEVMBuiltIn), | ||
} | ||
|
||
impl Parse for FnType { | ||
fn parse(input: ParseStream<'_>) -> Result<Self> { | ||
let speculative_parse = input.fork(); | ||
|
||
if let Ok(evm_builtin) = speculative_parse.parse::<YulEVMBuiltIn>() { | ||
input.advance_to(&speculative_parse); | ||
Ok(Self::EVMOpcode(evm_builtin)) | ||
} else { | ||
Ok(Self::Custom(input.parse::<YulIdent>()?)) | ||
} | ||
} | ||
} | ||
|
||
impl Spanned for FnType { | ||
fn span(&self) -> Span { | ||
match self { | ||
Self::Custom(custom) => custom.span(), | ||
Self::EVMOpcode(opcode) => opcode.span(), | ||
} | ||
} | ||
|
||
fn set_span(&mut self, span: Span) { | ||
match self { | ||
Self::Custom(custom) => custom.set_span(span), | ||
Self::EVMOpcode(opcode) => opcode.set_span(span), | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Debug for FnType { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.write_str("FnType::")?; | ||
match self { | ||
Self::Custom(custom) => custom.fmt(f), | ||
Self::EVMOpcode(opcode) => opcode.fmt(f), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use crate::{Lit, Spanned, YulPath}; | ||
|
||
use std::fmt; | ||
|
||
use proc_macro2::Span; | ||
use syn::{ | ||
parse::{discouraged::Speculative, Parse, ParseStream, Result}, | ||
token::Paren, | ||
}; | ||
|
||
mod fn_call; | ||
pub use fn_call::YulFnCall; | ||
|
||
/// A Yul expression. | ||
/// | ||
/// Solidity Reference: | ||
/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.yulExpression> | ||
#[derive(Clone)] | ||
pub enum YulExpr { | ||
Path(YulPath), | ||
Call(YulFnCall), | ||
Literal(Lit), | ||
} | ||
|
||
impl Parse for YulExpr { | ||
fn parse(input: ParseStream<'_>) -> Result<Self> { | ||
if input.peek2(Paren) { | ||
return input.parse().map(Self::Call) | ||
} | ||
|
||
let speculative_parse = input.fork(); | ||
|
||
if let Ok(lit) = speculative_parse.parse::<Lit>() { | ||
input.advance_to(&speculative_parse); | ||
return Ok(Self::Literal(lit)) | ||
} | ||
|
||
input.parse().map(Self::Path) | ||
} | ||
} | ||
|
||
impl Spanned for YulExpr { | ||
fn span(&self) -> Span { | ||
match self { | ||
Self::Path(path) => path.span(), | ||
Self::Call(call) => call.span(), | ||
Self::Literal(lit) => lit.span(), | ||
} | ||
} | ||
|
||
fn set_span(&mut self, span: Span) { | ||
match self { | ||
Self::Path(path) => path.set_span(span), | ||
Self::Call(call) => call.set_span(span), | ||
Self::Literal(lit) => lit.set_span(span), | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Debug for YulExpr { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.write_str("YulExpr::")?; | ||
match self { | ||
Self::Path(path) => path.fmt(f), | ||
Self::Call(call) => call.fmt(f), | ||
Self::Literal(lit) => lit.fmt(f), | ||
} | ||
} | ||
} |
Oops, something went wrong.