solidity 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e72e223ba2202849d7dbb405a56b1edf7345b911813b3449bbf2059a9ebe87e5
4
- data.tar.gz: 2aa7d53cc55bc04929440cb3c49c99b85cc3efe0a151d24f9b887c2ac6297f09
3
+ metadata.gz: 2450cdadc297a615031d2a910fc70e39b6a29514ee4387e532bb3a7febec7fb4
4
+ data.tar.gz: 572f8c43f7cc641fc3d970b00287eec3e9adf7412ad046950d0bfa116930822c
5
5
  SHA512:
6
- metadata.gz: 25a530da83da24bbbf6ae85bc97a4ecac8d27eb0745d2952f3f43fda6ad3422021d798edffcafc9e03afcf6bd6d0c7985103fec52caa34987ffdb5d84a8699fd
7
- data.tar.gz: '09339328d15e47d6d9a6345f000cbc1dee7fce14dee04e14765f82add73824dbce6fa41ba0dfe1a190059b5aeef93b6c27dc3acf759f67bb0348556098f127e5'
6
+ metadata.gz: 2cdb28abe2cafb57f53df2d07af8a61c0f4c80177b0267bd7de2fa1afb96d423ff2399d628f11f34edd6896eaaeb4af3ebed5aa2b3489817c49c20560a536818
7
+ data.tar.gz: bcef0cdea7f22b7960db8269738d612d6a51f46626560762e8e85ffd52dc343e8a3d652de74b1d4c6ca89ee98fe7a1066a4de85535b5c704e1d6aa732bef7033
data/README.md CHANGED
@@ -24,9 +24,7 @@ Get / generate outline from source in the solidity (`.sol`) contract programming
24
24
  ].each do |addr|
25
25
 
26
26
  path = "awesome-contracts/address/#{addr}/contract.sol"
27
- txt = read_text( path )
28
-
29
- parser = Solidity::Parser.new( txt )
27
+ parser = Solidity::Parser.read( path )
30
28
 
31
29
  puts "---"
32
30
  puts "outline:"
@@ -67,6 +65,7 @@ library Address
67
65
  library Base64
68
66
  abstract contract Context
69
67
  library MerkleProof
68
+ interface ERC721A__IERC721Receiver
70
69
  contract ERC721A is IERC721A
71
70
  interface IERC721A
72
71
  ```
@@ -3,7 +3,7 @@ module Solidity
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- PATCH = 1
6
+ PATCH = 2
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
data/lib/solidity.rb CHANGED
@@ -10,74 +10,132 @@ require_relative 'solidity/version' # note: let version always go first
10
10
  module Solidity
11
11
 
12
12
  class Parser
13
+
14
+ def self.read( path )
15
+ txt = read_text( path )
16
+ new( txt )
17
+ end
18
+
19
+
20
+
13
21
  def initialize( txt )
14
22
  @txt = txt
15
23
  end
16
24
 
17
25
 
18
- SINGLE_COMMENT_RX = %r{^[ ]*//}
19
- MULTI_COMMENT_BEGIN_RX = %r{^[ ]*/\*}
20
- MULTI_COMMENT_END_RX = %r{\*/[ ]*$}
26
+ ###############
27
+ ## quotes
28
+ ##
29
+ ## note: regex pattern \\ needs to get escaped twice, thus, \\.
30
+ ## and for literal \\ use \\\\\.
31
+
32
+ ## => \\\\. -- allow backslash escapes e.g. \n \t \\ etc.
33
+ ## => [^`] -- everything except backquote
34
+
35
+ ## todo/fix - check if [^`] includes/matches newline too (yes)? -- add \n for multi-line!
36
+
37
+ SINGLE_QUOTE = %r{'
38
+ ( \\\\. | [^'] )*
39
+ '}x
21
40
 
22
- ID = '[a-zA-Z][a-zA-Z0-9]*'
41
+ DOUBLE_QUOTE = %r{"
42
+ ( \\\\. | [^"] )*
43
+ "}x
23
44
 
24
- PRAGMA_RX = %r{^[ ]*pragma}
25
- LIBRARY_RX = %r{^[ ]*library[ ]+(?<id>#{ID})[ \{]}
26
- ABSTRACT_CONTRACT_RX = %r{^[ ]*abstract[ ]+contract[ ]+(?<id>#{ID})[ \{]}
27
- CONTRACT_RX = %r{^[ ]*contract[ ]+(?<id>#{ID})[ \{]}
28
- INTERFACE_RX = %r{^[ ]*interface[ ]+(?<id>#{ID})[ \{]}
29
45
 
46
+ NAME = /[a-zA-Z][a-zA-Z0-9_]*/
47
+ END_OF_LINE = /\n|$/
48
+ ## inline comments (multi- or end-of-line)
49
+ END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE = / \n
50
+ | $
51
+ | (?=['"])
52
+ | (?=\/(\/|\*))
53
+ | (?=pragma\b)
54
+ | (?=contract\b)
55
+ | (?=abstract\b)
56
+ | (?=library\b)
57
+ | (?=interface\b)
58
+ /x
59
+
60
+
61
+ def _norm_whitespace( str )
62
+ ## change newlines to spaces and
63
+ ## all multiple spaces to one
64
+ str = str.gsub( /[ \t\n\r]+/, ' ' )
65
+ str.strip
66
+ end
30
67
 
31
68
  def _quick_pass_one
32
- tree = []
33
- node = nil
69
+ ## note: CANNOT handle inline comments
70
+ ## in pragma, contract, etc. (get "silently" slurped)
71
+ ## report a parse error - if comments slurped - why? why not?
72
+ ##
34
73
 
35
- inside_comment = false
36
74
 
37
- @txt.each_line do |line|
38
- line = line.chomp ## remove trailing newline
39
- ## pp line
75
+ tree = []
40
76
 
41
- if inside_comment
42
- node[1] << line
43
- if MULTI_COMMENT_END_RX.match( line )
44
- tree << node
45
- inside_comment = false
46
- end
47
- else
48
- if SINGLE_COMMENT_RX.match( line ) # end-of-line comments
49
- line = line.strip ## remove leading & trailing spaces
50
- ## note: fold end-of-line comments into a block (if not separated by newline)
51
- node = tree[-1]
52
- if node.is_a?( Array ) &&
53
- node[0] == :comment && node[1][0].start_with?( '//' )
54
- node[1] << line
55
- else
56
- tree << [:comment, [line]]
57
- end
58
- elsif MULTI_COMMENT_BEGIN_RX.match( line )
59
- inside_comment = true
60
- node = [:comment, [line]]
61
- elsif PRAGMA_RX.match( line )
62
- line = line.strip
63
- tree << [:pragma, line]
64
- elsif LIBRARY_RX.match( line )
65
- line = line.strip
66
- tree << [:library, line]
67
- elsif ABSTRACT_CONTRACT_RX.match( line )
68
- line = line.strip
69
- tree << [:abstract_contract, line]
70
- elsif CONTRACT_RX.match( line )
71
- line = line.strip
72
- tree << [:contract, line]
73
- elsif INTERFACE_RX.match( line )
74
- line = line.strip
75
- tree << [:interface, line]
76
- else
77
- tree << line
78
- end
79
- end
80
- end # each_line
77
+ s = StringScanner.new( @txt )
78
+
79
+ loop do
80
+ s.skip( /[ \t]+/ ) ## note: do NOT skip newlines here; pass along blank/empty lines for now - why? why not?
81
+ if s.check( "'" ) ## single-quoted string
82
+ str = s.scan( SINGLE_QUOTE )
83
+ tree << [:string, str]
84
+ elsif s.check( '"' ) ## double-quoted string
85
+ str = s.scan( DOUBLE_QUOTE )
86
+ tree << [:string, str]
87
+ elsif s.check( '/*' )
88
+ comment = s.scan_until( /\*\// )
89
+ ## print "multi-line comment:"
90
+ ## pp comment
91
+ tree << [:comment, comment]
92
+ elsif s.check( '//' )
93
+ comment = s.scan_until( END_OF_LINE ).rstrip
94
+ ## print "comment:"
95
+ ## pp comment
96
+ tree << [:comment, comment]
97
+ else
98
+ name = s.check( NAME )
99
+ case name
100
+ when 'pragma'
101
+ code = s.scan_until( /;/ )
102
+ code = _norm_whitespace( code )
103
+ ## print "pragma:"
104
+ ## pp code
105
+ tree << [:pragma, code]
106
+ when 'contract'
107
+ code = s.scan_until( /(?=\{)/ )
108
+ code = _norm_whitespace( code )
109
+ ## print "contract:"
110
+ ## pp code
111
+ tree << [:contract, code]
112
+ when 'abstract'
113
+ code = s.scan_until( /(?=\{)/ )
114
+ code = _norm_whitespace( code )
115
+ ## print "abstract contract:"
116
+ ## pp code
117
+ tree << [:abstract_contract, code]
118
+ when 'library'
119
+ code = s.scan_until( /(?=\{)/ )
120
+ code = _norm_whitespace( code )
121
+ ## print "library:"
122
+ ## pp code
123
+ tree << [:library, code]
124
+ when 'interface'
125
+ code = s.scan_until( /(?=\{)/ )
126
+ code = _norm_whitespace( code )
127
+ ## print "interface:"
128
+ ## pp code
129
+ tree << [:interface, code]
130
+ else
131
+ ## slurp chunk ,that is, until newline or comment or tracked keyword
132
+ chunk = s.scan_until( END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE ).rstrip
133
+ ## puts "chunk: >#{chunk.inspect}<"
134
+ tree << chunk
135
+ end
136
+ end
137
+ break if s.eos?
138
+ end
81
139
 
82
140
  tree
83
141
  end
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.1
4
+ version: 0.1.2
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-01-29 00:00:00.000000000 Z
11
+ date: 2023-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocos