solidity 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Manifest.txt +1 -0
- data/README.md +11 -46
- data/Rakefile +1 -1
- data/lib/solidity/lexer.rb +166 -0
- data/lib/solidity/parser.rb +55 -135
- data/lib/solidity/version.rb +1 -1
- data/lib/solidity.rb +1 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7039440cfd0f451c6d990c35cdbef3a23309b86ce3c380cb4716ad9647b27f5d
|
4
|
+
data.tar.gz: e69c2a1a4273a5c9abc2858d5fe5a9cc27dc46656acf321e39cb520addb579c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a97fb7eeac099baf18b2045fa60351b97ac36207c68517553498c35912f4eed73727aa94d8e9b70a7b2512e9efeb865d764161fa56876c1fcac2f87782333049
|
7
|
+
data.tar.gz: 68abe7d1bb83abdbd5a45f6cd3303a9ff368ae87f73046a9f3d40858e4407fc4f8fb300e599aca915a68921a9d3ff286b88ae4b29746e5fcd7b2ac0d2634f324
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,23 +1,6 @@
|
|
1
|
-
|
2
|
-
---
|
3
|
-
|
4
|
-
_The Ruby Programming Language for Contract / Transaction Scripts on the Blockchain World Computer - Yes, It's Just Ruby_
|
5
|
-
|
6
|
-
**sruby - Small, Smart, Secure, Safe, Solid & Sound (S6) Ruby**
|
7
|
-
|
8
|
-
sruby is a subset of mruby that is a subset of "classic" ruby.
|
9
|
-
|
10
|
-
|
11
|
-
For more see the [**Red Paper »**](https://github.com/s6ruby/redpaper)
|
12
|
-
|
13
|
-
---
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
1
|
# Solidity
|
19
2
|
|
20
|
-
solidity gem - (fuzzy) parser for (crypto) contracts for ethereum & co.
|
3
|
+
solidity gem - (fuzzy) lexer & parser for (crypto) contracts for ethereum & co.
|
21
4
|
|
22
5
|
|
23
6
|
* home :: [github.com/rubycocos/blockchain](https://github.com/rubycocos/blockchain)
|
@@ -29,25 +12,7 @@ solidity gem - (fuzzy) parser for (crypto) contracts for ethereum & co.
|
|
29
12
|
|
30
13
|
## New to the Solidity (Contract) Programming Language?
|
31
14
|
|
32
|
-
|
33
|
-
|
34
|
-
Solidity Language @ <https://soliditylang.org>
|
35
|
-
|
36
|
-
- Read the Docs @ <https://docs.soliditylang.org/en/latest/>
|
37
|
-
- Blog @ <https://blog.soliditylang.org>
|
38
|
-
- Forum @ <https://forum.soliditylang.org>
|
39
|
-
- Source @ <https://github.com/ethereum/solidity>
|
40
|
-
|
41
|
-
<!-- break -->
|
42
|
-
|
43
|
-
_More_
|
44
|
-
|
45
|
-
Solidity by Example @ <https://solidity-by-example.org>
|
46
|
-
|
47
|
-
Learn X in Y Minutes (Where X=Solidity) @ <https://learnxinyminutes.com/docs/solidity>
|
48
|
-
|
49
|
-
Awesome Solidity @ <https://github.com/bkrem/awesome-solidity>
|
50
|
-
|
15
|
+
See [**Awesome Solidity @ Open Blockchains »**](https://github.com/openblockchains/awesome-solidity)
|
51
16
|
|
52
17
|
|
53
18
|
|
@@ -95,24 +60,24 @@ Note: The outline includes:
|
|
95
60
|
|
96
61
|
1. contract definitions e.g.
|
97
62
|
|
98
|
-
|
63
|
+
contract NounsDescriptor is INounsDescriptor, Ownable
|
99
64
|
|
100
65
|
2. abstract contract definitions e.g.
|
101
66
|
|
102
|
-
|
103
|
-
|
67
|
+
abstract contract Ownable is Context
|
68
|
+
abstract contract Context
|
104
69
|
|
105
70
|
3. library definitions e.g.
|
106
71
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
72
|
+
library Strings
|
73
|
+
library NFTDescriptor
|
74
|
+
library MultiPartRLEToSVG
|
75
|
+
library Base64
|
111
76
|
|
112
77
|
4. interface definitions e.g.
|
113
78
|
|
114
|
-
|
115
|
-
|
79
|
+
interface INounsDescriptor
|
80
|
+
interface INounsSeeder
|
116
81
|
|
117
82
|
|
118
83
|
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ Hoe.spec 'solidity' do
|
|
14
14
|
|
15
15
|
self.version = Solidity::VERSION
|
16
16
|
|
17
|
-
self.summary = "solidity - (fuzzy) parser for (crypto) contracts for ethereum & co."
|
17
|
+
self.summary = "solidity - (fuzzy) lexer & parser for (crypto) contracts for ethereum & co."
|
18
18
|
self.description = summary
|
19
19
|
|
20
20
|
self.urls = { home: 'https://github.com/rubycocos/blockchain' }
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module Solidity
|
2
|
+
|
3
|
+
class Lexer
|
4
|
+
|
5
|
+
def self.read( path )
|
6
|
+
txt = read_text( path )
|
7
|
+
new( txt )
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
def initialize( txt )
|
13
|
+
@txt = txt
|
14
|
+
@tokens = tokenize
|
15
|
+
@pos = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
###############
|
21
|
+
## quotes
|
22
|
+
##
|
23
|
+
## note: regex pattern \\ needs to get escaped twice, thus, \\.
|
24
|
+
## and for literal \\ use \\\\\.
|
25
|
+
|
26
|
+
## => \\\\. -- allow backslash escapes e.g. \n \t \\ etc.
|
27
|
+
## => [^`] -- everything except backquote
|
28
|
+
|
29
|
+
## todo/fix - check if [^`] includes/matches newline too (yes)? -- add \n for multi-line!
|
30
|
+
|
31
|
+
|
32
|
+
## from the solidity grammar
|
33
|
+
##
|
34
|
+
## StringLiteralFragment
|
35
|
+
## : 'unicode'? '"' DoubleQuotedStringCharacter* '"'
|
36
|
+
## | 'unicode'? '\'' SingleQuotedStringCharacter* '\'' ;
|
37
|
+
##
|
38
|
+
## fragment
|
39
|
+
## DoubleQuotedStringCharacter
|
40
|
+
## : ~["\r\n\\] | ('\\' .) ;
|
41
|
+
##
|
42
|
+
## fragment
|
43
|
+
## SingleQuotedStringCharacter
|
44
|
+
## : ~['\r\n\\] | ('\\' .) ;
|
45
|
+
|
46
|
+
|
47
|
+
SINGLE_QUOTE = %r{'
|
48
|
+
( \\\\. | [^'] )*
|
49
|
+
'}x
|
50
|
+
|
51
|
+
DOUBLE_QUOTE = %r{"
|
52
|
+
( \\\\. | [^"] )*
|
53
|
+
"}x
|
54
|
+
|
55
|
+
|
56
|
+
## from the solidity grammar
|
57
|
+
## > An identifier in solidity has to start with a letter,
|
58
|
+
## > a dollar-sign or an underscore and
|
59
|
+
## > may additionally contain numbers after the first symbol.
|
60
|
+
##
|
61
|
+
## Identifier
|
62
|
+
## : IdentifierStart IdentifierPart* ;
|
63
|
+
##
|
64
|
+
## fragment
|
65
|
+
## IdentifierStart
|
66
|
+
## : [a-zA-Z$_] ;
|
67
|
+
##
|
68
|
+
## fragment
|
69
|
+
## IdentifierPart
|
70
|
+
## : [a-zA-Z0-9$_] ;
|
71
|
+
|
72
|
+
NAME = /[a-zA-Z$_][a-zA-Z0-9$_]*/
|
73
|
+
|
74
|
+
|
75
|
+
## from the solidity grammar
|
76
|
+
##
|
77
|
+
## COMMENT
|
78
|
+
## : '/*' .*? '*/' ;
|
79
|
+
##
|
80
|
+
## LINE_COMMENT
|
81
|
+
## : '//' ~[\r\n]* ;
|
82
|
+
|
83
|
+
|
84
|
+
def tokenize
|
85
|
+
t = []
|
86
|
+
s = StringScanner.new( @txt )
|
87
|
+
|
88
|
+
until s.eos? ## loop until hitting end-of-string (file)
|
89
|
+
if s.check( /[ \t]*\/\*/ )
|
90
|
+
## note: auto-slurp leading (optinal) spaces!!!! - why? why not?
|
91
|
+
comment = s.scan_until( /\*\// )
|
92
|
+
## print "multi-line comment:"
|
93
|
+
## pp comment
|
94
|
+
t << [:comment, comment.lstrip]
|
95
|
+
elsif s.check( /[ \t]*\/\// )
|
96
|
+
## note: auto-slurp leading (optinal) spaces!!!! - why? why not?
|
97
|
+
## note: auto-remove newline AND trailing whitespace - why? why not?
|
98
|
+
comment = s.scan_until( /\n|$/ ).strip
|
99
|
+
## print "comment:"
|
100
|
+
## pp comment
|
101
|
+
t << [:comment, comment]
|
102
|
+
elsif s.scan( /[ \t]+/ ) ## one or more spaces
|
103
|
+
## note: (auto-)convert tab to space - why? why not?
|
104
|
+
t << [:sp, s.matched.gsub( /[\t]/, ' ') ]
|
105
|
+
elsif s.scan( /\r?\n/ ) ## check for (windows) carriage return (\r) - why? why not?
|
106
|
+
t << [:nl, "\n" ]
|
107
|
+
elsif s.check( "'" ) ## single-quoted string
|
108
|
+
str = s.scan( SINGLE_QUOTE )
|
109
|
+
t << [:string, str]
|
110
|
+
elsif s.check( '"' ) ## double-quoted string
|
111
|
+
str = s.scan( DOUBLE_QUOTE )
|
112
|
+
t << [:string, str]
|
113
|
+
elsif s.scan( NAME )
|
114
|
+
name = s.matched
|
115
|
+
case name
|
116
|
+
when 'pragma' then t << [:pragma, name]
|
117
|
+
when 'contract' then t << [:contract, name]
|
118
|
+
when 'abstract' then t << [:abstract, name]
|
119
|
+
when 'library' then t << [:library, name]
|
120
|
+
when 'interface' then t << [:interface, name]
|
121
|
+
when 'function' then t << [:function, name]
|
122
|
+
when 'struct' then t << [:struct, name]
|
123
|
+
when 'enum' then t << [:enum, name]
|
124
|
+
when 'event' then t << [:event, name]
|
125
|
+
else
|
126
|
+
t << [:ident, name]
|
127
|
+
end
|
128
|
+
elsif s.scan( /;/ ) then t << [:';', ';']
|
129
|
+
elsif s.scan( /\{/ ) then t << [:'{', '{']
|
130
|
+
elsif s.scan( /\}/ ) then t << [:'}', '}']
|
131
|
+
else ## slurp until hitting a "tracked" token again
|
132
|
+
last = t[-1]
|
133
|
+
if last.is_a?( String )
|
134
|
+
last << s.getch ## append char to last chunk
|
135
|
+
else
|
136
|
+
t << s.getch ## start a new chunk
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
t
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
def reset() @pos = 0; end
|
146
|
+
def pos() @pos; end
|
147
|
+
def peek
|
148
|
+
## note: returns token type for now (e.g. :string, :sp, etc.)
|
149
|
+
## and NOT token struct for now - why? why not?
|
150
|
+
t = @tokens[@pos]
|
151
|
+
t.nil? || t.is_a?( String ) ? t : t[0]
|
152
|
+
end
|
153
|
+
def next
|
154
|
+
## note: returns type lexeme (string content) for now
|
155
|
+
## and NOT token struct for now - why? why not?
|
156
|
+
t = @tokens[@pos]
|
157
|
+
tt = t.nil? || t.is_a?( String ) ? t : t[1]
|
158
|
+
@pos += 1 unless t.nil?
|
159
|
+
tt
|
160
|
+
end
|
161
|
+
def eos?() peek().nil?; end
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
end # class Lexer
|
166
|
+
end # module Solidity
|
data/lib/solidity/parser.rb
CHANGED
@@ -14,85 +14,25 @@ class Parser
|
|
14
14
|
end
|
15
15
|
|
16
16
|
|
17
|
-
###############
|
18
|
-
## quotes
|
19
|
-
##
|
20
|
-
## note: regex pattern \\ needs to get escaped twice, thus, \\.
|
21
|
-
## and for literal \\ use \\\\\.
|
22
|
-
|
23
|
-
## => \\\\. -- allow backslash escapes e.g. \n \t \\ etc.
|
24
|
-
## => [^`] -- everything except backquote
|
25
|
-
|
26
|
-
## todo/fix - check if [^`] includes/matches newline too (yes)? -- add \n for multi-line!
|
27
|
-
|
28
|
-
|
29
|
-
## from the solidity grammar
|
30
|
-
##
|
31
|
-
## StringLiteralFragment
|
32
|
-
## : 'unicode'? '"' DoubleQuotedStringCharacter* '"'
|
33
|
-
## | 'unicode'? '\'' SingleQuotedStringCharacter* '\'' ;
|
34
|
-
##
|
35
|
-
## fragment
|
36
|
-
## DoubleQuotedStringCharacter
|
37
|
-
## : ~["\r\n\\] | ('\\' .) ;
|
38
|
-
##
|
39
|
-
## fragment
|
40
|
-
## SingleQuotedStringCharacter
|
41
|
-
## : ~['\r\n\\] | ('\\' .) ;
|
42
|
-
|
43
|
-
|
44
|
-
SINGLE_QUOTE = %r{'
|
45
|
-
( \\\\. | [^'] )*
|
46
|
-
'}x
|
47
|
-
|
48
|
-
DOUBLE_QUOTE = %r{"
|
49
|
-
( \\\\. | [^"] )*
|
50
|
-
"}x
|
51
|
-
|
52
|
-
|
53
|
-
## from the solidity grammar
|
54
|
-
## > An identifier in solidity has to start with a letter,
|
55
|
-
## > a dollar-sign or an underscore and
|
56
|
-
## > may additionally contain numbers after the first symbol.
|
57
|
-
##
|
58
|
-
## Identifier
|
59
|
-
## : IdentifierStart IdentifierPart* ;
|
60
|
-
##
|
61
|
-
## fragment
|
62
|
-
## IdentifierStart
|
63
|
-
## : [a-zA-Z$_] ;
|
64
|
-
##
|
65
|
-
## fragment
|
66
|
-
## IdentifierPart
|
67
|
-
## : [a-zA-Z0-9$_] ;
|
68
|
-
|
69
|
-
NAME = /[a-zA-Z$_][a-zA-Z0-9$_]*/
|
70
|
-
|
71
|
-
|
72
|
-
END_OF_LINE = /\n|$/
|
73
|
-
## inline comments (multi- or end-of-line)
|
74
|
-
END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE = / \n
|
75
|
-
| $
|
76
|
-
| (?=['"])
|
77
|
-
| (?=\/(\/|\*))
|
78
|
-
| (?=\bpragma\b)
|
79
|
-
| (?=\bcontract\b)
|
80
|
-
| (?=\babstract\b)
|
81
|
-
| (?=\blibrary\b)
|
82
|
-
| (?=\binterface\b)
|
83
|
-
/x
|
84
|
-
|
85
|
-
|
86
|
-
## from the solidity grammar
|
87
|
-
##
|
88
|
-
## COMMENT
|
89
|
-
## : '/*' .*? '*/' ;
|
90
|
-
##
|
91
|
-
## LINE_COMMENT
|
92
|
-
## : '//' ~[\r\n]* ;
|
93
17
|
|
94
18
|
|
95
19
|
|
20
|
+
def _scan_until( lex, tt, include: false )
|
21
|
+
code = String.new('')
|
22
|
+
while (peek=lex.peek) != tt do
|
23
|
+
## note: turn inline comments into a single space
|
24
|
+
code << if peek == :comment
|
25
|
+
lex.next
|
26
|
+
' '
|
27
|
+
else
|
28
|
+
lex.next
|
29
|
+
end
|
30
|
+
end
|
31
|
+
code << lex.next if include ## include ';' too - why? why not?
|
32
|
+
code = _norm_whitespace( code )
|
33
|
+
code
|
34
|
+
end
|
35
|
+
|
96
36
|
def _norm_whitespace( str )
|
97
37
|
## change newlines to spaces and
|
98
38
|
## all multiple spaces to one
|
@@ -100,82 +40,62 @@ class Parser
|
|
100
40
|
str.strip
|
101
41
|
end
|
102
42
|
|
43
|
+
|
103
44
|
def _quick_pass_one
|
104
|
-
|
105
|
-
## in pragma, contract, etc. (get "silently" slurped)
|
106
|
-
## report a parse error - if comments slurped - why? why not?
|
107
|
-
##
|
45
|
+
tree = []
|
108
46
|
|
47
|
+
lex = Lexer.new( @txt )
|
109
48
|
|
110
|
-
|
49
|
+
until lex.eos?
|
50
|
+
while lex.peek == :sp do ## note: do NOT skip newlines here; pass along blank/empty lines for now - why? why not?
|
51
|
+
lex.next
|
52
|
+
end
|
111
53
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
tree << [:string, str]
|
119
|
-
elsif s.check( '"' ) ## double-quoted string
|
120
|
-
str = s.scan( DOUBLE_QUOTE )
|
121
|
-
tree << [:string, str]
|
122
|
-
elsif s.check( '/*' )
|
123
|
-
comment = s.scan_until( /\*\// )
|
124
|
-
## print "multi-line comment:"
|
125
|
-
## pp comment
|
126
|
-
tree << [:comment, comment]
|
127
|
-
elsif s.check( '//' )
|
128
|
-
comment = s.scan_until( END_OF_LINE ).rstrip
|
129
|
-
## print "comment:"
|
130
|
-
## pp comment
|
131
|
-
tree << [:comment, comment]
|
132
|
-
else
|
133
|
-
name = s.check( NAME )
|
134
|
-
case name
|
135
|
-
when 'pragma'
|
136
|
-
code = s.scan_until( /;/ )
|
137
|
-
code = _norm_whitespace( code )
|
54
|
+
case lex.peek
|
55
|
+
when :comment ## single or multi-line comment
|
56
|
+
tree << [:comment, lex.next]
|
57
|
+
when :pragma
|
58
|
+
code = _scan_until( lex, :';',
|
59
|
+
include: true )
|
138
60
|
## print "pragma:"
|
139
61
|
## pp code
|
140
62
|
tree << [:pragma, code]
|
141
|
-
|
142
|
-
code =
|
143
|
-
code = _norm_whitespace( code )
|
63
|
+
when :contract
|
64
|
+
code = _scan_until( lex, :'{' )
|
144
65
|
## print "contract:"
|
145
66
|
## pp code
|
146
67
|
tree << [:contract, code]
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
## pp code
|
164
|
-
tree << [:interface, code]
|
165
|
-
else
|
68
|
+
when :abstract
|
69
|
+
code = _scan_until( lex, :'{' )
|
70
|
+
## print "abstract contract:"
|
71
|
+
## pp code
|
72
|
+
tree << [:abstract_contract, code]
|
73
|
+
when :library
|
74
|
+
code = _scan_until( lex, :'{' )
|
75
|
+
## print "library:"
|
76
|
+
## pp code
|
77
|
+
tree << [:library, code]
|
78
|
+
when :interface
|
79
|
+
code = _scan_until( lex, :'{' )
|
80
|
+
## print "interface:"
|
81
|
+
## pp code
|
82
|
+
tree << [:interface, code]
|
83
|
+
else
|
166
84
|
## slurp chunk ,that is, until newline or comment or tracked keyword
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
85
|
+
last = tree[-1]
|
86
|
+
if last.is_a?( String )
|
87
|
+
last << lex.next ## append lexeme to last chunk
|
88
|
+
else
|
89
|
+
tree << lex.next ## start a new chunk
|
90
|
+
end
|
171
91
|
end
|
172
|
-
|
173
|
-
end
|
92
|
+
end
|
174
93
|
|
175
94
|
tree
|
176
95
|
end
|
177
96
|
|
178
97
|
|
98
|
+
|
179
99
|
def outline
|
180
100
|
buf = String.new( '' )
|
181
101
|
tree = _quick_pass_one
|
data/lib/solidity/version.rb
CHANGED
data/lib/solidity.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solidity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cocos
|
@@ -58,7 +58,8 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '3.23'
|
61
|
-
description: solidity - (fuzzy) parser for (crypto) contracts for ethereum
|
61
|
+
description: solidity - (fuzzy) lexer & parser for (crypto) contracts for ethereum
|
62
|
+
& co.
|
62
63
|
email: wwwmake@googlegroups.com
|
63
64
|
executables: []
|
64
65
|
extensions: []
|
@@ -72,6 +73,7 @@ files:
|
|
72
73
|
- README.md
|
73
74
|
- Rakefile
|
74
75
|
- lib/solidity.rb
|
76
|
+
- lib/solidity/lexer.rb
|
75
77
|
- lib/solidity/parser.rb
|
76
78
|
- lib/solidity/version.rb
|
77
79
|
homepage: https://github.com/rubycocos/blockchain
|
@@ -98,5 +100,5 @@ requirements: []
|
|
98
100
|
rubygems_version: 3.3.7
|
99
101
|
signing_key:
|
100
102
|
specification_version: 4
|
101
|
-
summary: solidity - (fuzzy) parser for (crypto) contracts for ethereum & co.
|
103
|
+
summary: solidity - (fuzzy) lexer & parser for (crypto) contracts for ethereum & co.
|
102
104
|
test_files: []
|