solidity 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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: []