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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3920e32ab53156b256507811437d64f62f38bd42472aecb5c51a4fd3eb2f57e1
4
- data.tar.gz: 4a5c36c583ba102881417af5d184c6351ef9d6a1f20154ab6096fb4722694bc6
3
+ metadata.gz: 7039440cfd0f451c6d990c35cdbef3a23309b86ce3c380cb4716ad9647b27f5d
4
+ data.tar.gz: e69c2a1a4273a5c9abc2858d5fe5a9cc27dc46656acf321e39cb520addb579c1
5
5
  SHA512:
6
- metadata.gz: b7227cdec56deceba0230c0f8946ea0182e2e144919bb2b0227d52a19c4085d89a0b2f3a62c796b162c9fba59880d5ee1cb154bfc0f5de1455cb4bd353d4602d
7
- data.tar.gz: 9840c43aade93aaec0b0222c2db7dc4f50246565da9e52c69363fe599e43bed8e0e800ac31349a846ab7cfeb4e28126bde9fcfd8d6a85b884d9d26240b1fc35b
6
+ metadata.gz: a97fb7eeac099baf18b2045fa60351b97ac36207c68517553498c35912f4eed73727aa94d8e9b70a7b2512e9efeb865d764161fa56876c1fcac2f87782333049
7
+ data.tar.gz: 68abe7d1bb83abdbd5a45f6cd3303a9ff368ae87f73046a9f3d40858e4407fc4f8fb300e599aca915a68921a9d3ff286b88ae4b29746e5fcd7b2ac0d2634f324
data/Manifest.txt CHANGED
@@ -3,5 +3,6 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/solidity.rb
6
+ lib/solidity/lexer.rb
6
7
  lib/solidity/parser.rb
7
8
  lib/solidity/version.rb
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
- _Official_
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
- contract NounsDescriptor is INounsDescriptor, Ownable
63
+ contract NounsDescriptor is INounsDescriptor, Ownable
99
64
 
100
65
  2. abstract contract definitions e.g.
101
66
 
102
- abstract contract Ownable is Context
103
- abstract contract Context
67
+ abstract contract Ownable is Context
68
+ abstract contract Context
104
69
 
105
70
  3. library definitions e.g.
106
71
 
107
- library Strings
108
- library NFTDescriptor
109
- library MultiPartRLEToSVG
110
- library Base64
72
+ library Strings
73
+ library NFTDescriptor
74
+ library MultiPartRLEToSVG
75
+ library Base64
111
76
 
112
77
  4. interface definitions e.g.
113
78
 
114
- interface INounsDescriptor
115
- interface INounsSeeder
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
@@ -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
- ## note: CANNOT handle inline comments
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
- tree = []
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
- s = StringScanner.new( @txt )
113
-
114
- loop do
115
- s.skip( /[ \t]+/ ) ## note: do NOT skip newlines here; pass along blank/empty lines for now - why? why not?
116
- if s.check( "'" ) ## single-quoted string
117
- str = s.scan( SINGLE_QUOTE )
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
- when 'contract'
142
- code = s.scan_until( /(?=\{)/ )
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
- when 'abstract'
148
- code = s.scan_until( /(?=\{)/ )
149
- code = _norm_whitespace( code )
150
- ## print "abstract contract:"
151
- ## pp code
152
- tree << [:abstract_contract, code]
153
- when 'library'
154
- code = s.scan_until( /(?=\{)/ )
155
- code = _norm_whitespace( code )
156
- ## print "library:"
157
- ## pp code
158
- tree << [:library, code]
159
- when 'interface'
160
- code = s.scan_until( /(?=\{)/ )
161
- code = _norm_whitespace( code )
162
- ## print "interface:"
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
- chunk = s.scan_until( END_OF_LINE_OR_COMMENT_OR_KEYWORD_OR_QUOTE ).rstrip
168
- ## puts "chunk: >#{chunk.inspect}<"
169
- tree << chunk
170
- end
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
- break if s.eos?
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
@@ -2,7 +2,7 @@
2
2
  module Solidity
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 4
5
+ PATCH = 5
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
data/lib/solidity.rb CHANGED
@@ -3,6 +3,7 @@ require 'cocos'
3
3
 
4
4
  ## our own code
5
5
  require_relative 'solidity/version' # note: let version always go first
6
+ require_relative 'solidity/lexer'
6
7
  require_relative 'solidity/parser'
7
8
 
8
9
 
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
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-01 00:00:00.000000000 Z
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 & co.
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: []