gettc 1.10 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/gettc +60 -69
- data/dist/config.yml +1 -1
- data/dist/include/cpp/engine.rb +78 -86
- data/dist/include/cpp/topcoder +236 -236
- data/dist/include/go/engine.rb +53 -61
- data/dist/include/haskell/engine.rb +112 -122
- data/dist/include/java/engine.rb +187 -184
- data/dist/include/javascript/engine.rb +26 -30
- data/dist/include/javascript/topcoder.js +3 -3
- data/dist/include/javascript/topcoder/errors.js +5 -5
- data/dist/include/javascript/topcoder/reader.js +188 -165
- data/dist/include/javascript/topcoder/writer.js +37 -33
- data/dist/include/python/engine.rb +43 -52
- data/dist/include/python/topcoder/__init__.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/__init__.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/errors.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/reader.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/__pycache__/writer.cpython-34.pyc +0 -0
- data/dist/include/python/topcoder/errors.pyc +0 -0
- data/dist/include/python/topcoder/reader.pyc +0 -0
- data/dist/include/python/topcoder/writer.pyc +0 -0
- data/dist/include/ruby/engine.rb +47 -52
- data/dist/include/ruby/topcoder/reader.rb +205 -193
- data/dist/include/ruby/topcoder/writer.rb +39 -37
- data/dist/template/bin/runner.rb +146 -151
- data/dist/template/bin/runner.sh +96 -96
- data/dist/template/prob/{name}.html +1 -1
- data/dist/template/solve/cpp/{name}.cpp +3 -4
- data/dist/template/solve/cpp/{name}Solver.cpp +14 -14
- data/dist/template/solve/go/{name}/{name}.go +3 -3
- data/dist/template/solve/go/{name}Solver.go +2 -2
- data/dist/template/solve/haskell/{name}.hs +6 -6
- data/dist/template/solve/haskell/{name}Solver.hs +10 -10
- data/dist/template/solve/java/{name}.java +4 -4
- data/dist/template/solve/java/{name}Solver.java +4 -4
- data/dist/template/solve/javascript/{name}.js +4 -6
- data/dist/template/solve/javascript/{name}Solver.js +11 -9
- data/dist/template/solve/python/{name}.py +1 -1
- data/dist/template/solve/python/{name}Solver.py +2 -2
- data/dist/template/solve/ruby/{name}.rb +4 -4
- data/dist/template/solve/ruby/{name}Solver.rb +14 -17
- data/dist/template/util/check/check.cpp +19 -19
- data/{core/lib → lib}/gettc.rb +0 -0
- data/lib/gettc/account.rb +14 -0
- data/lib/gettc/download.rb +211 -0
- data/lib/gettc/generate.rb +156 -0
- data/lib/gettc/parse.rb +237 -0
- data/lib/gettc/print.rb +54 -0
- data/lib/gettc/problem.rb +39 -0
- data/lib/gettc/signature.rb +63 -0
- data/lib/gettc/types.rb +93 -0
- data/lib/version.rb +3 -0
- data/test/gettc/download_test.rb +61 -0
- data/test/gettc/generate_test.rb +70 -0
- data/test/gettc/parse_test.rb +78 -0
- data/test/gettc/signature_test.rb +71 -0
- data/test/gettc/types_test.rb +31 -0
- metadata +28 -23
- data/core/lib/gettc/download.rb +0 -130
- data/core/lib/gettc/generate.rb +0 -145
- data/core/lib/gettc/parse.rb +0 -233
- data/core/lib/gettc/print.rb +0 -56
- data/core/lib/gettc/problem.rb +0 -33
- data/core/lib/gettc/signature.rb +0 -55
- data/core/lib/gettc/types.rb +0 -83
- data/core/lib/version.rb +0 -3
- data/core/test/gettc/download_test.rb +0 -29
- data/core/test/gettc/generate_test.rb +0 -31
- data/core/test/gettc/parse_test.rb +0 -104
- data/core/test/gettc/signature_test.rb +0 -54
- data/core/test/gettc/types_test.rb +0 -28
@@ -1,46 +1,50 @@
|
|
1
1
|
var tc = require("./errors");
|
2
2
|
|
3
3
|
function Writer() {
|
4
|
-
|
4
|
+
this.text = "";
|
5
5
|
}
|
6
6
|
|
7
7
|
Writer.prototype.next = function(value, type) {
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
return this;
|
23
|
-
}
|
24
|
-
switch (type) {
|
25
|
-
case "boolean":
|
26
|
-
case "int":
|
27
|
-
case "long":
|
28
|
-
case "float":
|
29
|
-
case "double":
|
30
|
-
this.text += value.toString();
|
31
|
-
return this;
|
32
|
-
case "char":
|
33
|
-
this.text += "'" + value + "'";
|
34
|
-
return this;
|
35
|
-
case "String":
|
36
|
-
this.text += '"' + value + '"';
|
37
|
-
return this;
|
8
|
+
if (typeof(value) === "undefined") {
|
9
|
+
this.text += ", "
|
10
|
+
return this;
|
11
|
+
}
|
12
|
+
|
13
|
+
if (type.substr(type.length - 2, 2) === "[]") {
|
14
|
+
var elemType = type.substr(0, type.length - 2);
|
15
|
+
this.text += '[';
|
16
|
+
|
17
|
+
for (var i = 0; i < value.length; ++i) {
|
18
|
+
this.next(value[i], elemType);
|
19
|
+
if (i < value.length - 1) {
|
20
|
+
this.next();
|
21
|
+
}
|
38
22
|
}
|
39
|
-
|
23
|
+
|
24
|
+
this.text += ']';
|
25
|
+
return this;
|
26
|
+
}
|
27
|
+
|
28
|
+
switch (type) {
|
29
|
+
case "boolean":
|
30
|
+
case "int":
|
31
|
+
case "long":
|
32
|
+
case "float":
|
33
|
+
case "double":
|
34
|
+
this.text += value.toString();
|
35
|
+
return this;
|
36
|
+
case "char":
|
37
|
+
this.text += "'" + value + "'";
|
38
|
+
return this;
|
39
|
+
case "String":
|
40
|
+
this.text += '"' + value + '"';
|
41
|
+
return this;
|
42
|
+
}
|
43
|
+
throw new tc.UnsupportedType(type);
|
40
44
|
};
|
41
45
|
|
42
46
|
Writer.prototype.toString = function() {
|
43
|
-
|
47
|
+
return this.text;
|
44
48
|
};
|
45
49
|
|
46
50
|
module.exports = Writer;
|
@@ -1,65 +1,56 @@
|
|
1
1
|
require "gettc/types"
|
2
2
|
|
3
3
|
module Gettc
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
class Type
|
5
|
+
def dumb_python
|
6
|
+
return "[]" if self.is_a?(TArray)
|
7
|
+
|
8
|
+
case self
|
9
|
+
when TInt, TLong, TFloat, TDouble
|
10
|
+
"0"
|
11
|
+
when TChar
|
12
|
+
"'$'"
|
13
|
+
when TString
|
14
|
+
'"$"'
|
15
|
+
when TBoolean
|
16
|
+
"True"
|
17
|
+
else
|
18
|
+
"None"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
9
22
|
|
10
|
-
|
11
|
-
|
12
|
-
return "0"
|
13
|
-
when TChar
|
14
|
-
return "'$'"
|
15
|
-
when TString
|
16
|
-
return '"$"'
|
17
|
-
when TBoolean
|
18
|
-
return "True"
|
19
|
-
end
|
23
|
+
class PythonEngine
|
24
|
+
attr_reader :arglist, :input, :shebang
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
class PythonEngine
|
25
|
-
attr_reader :arglist, :input, :shebang
|
26
|
-
def initialize func, vars
|
27
|
-
temp = vars.map do |var|
|
28
|
-
var.name
|
29
|
-
end
|
30
|
-
@arglist = temp.join ", "
|
26
|
+
def initialize(func, vars)
|
27
|
+
@arglist = vars.map(&:name).join(", ")
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
@input = vars.map do |var|
|
30
|
+
"#{var.name} = reader.next(\"#{var.type}\")"
|
31
|
+
end.join("\nreader.next()\n")
|
32
|
+
|
33
|
+
@shebang = "#! #{python3_path}"
|
34
|
+
end
|
36
35
|
|
37
|
-
@shebang = "#! "
|
38
|
-
@shebang << python3_path
|
39
|
-
end
|
40
36
|
private
|
41
|
-
def python3_path
|
42
|
-
default = "/usr/bin/env python"
|
43
37
|
|
44
|
-
|
45
|
-
|
46
|
-
return default
|
47
|
-
end
|
38
|
+
def python3_path
|
39
|
+
default = "/usr/bin/env python"
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
41
|
+
version = system_q("python --version").split
|
42
|
+
return default if version.size != 2 || version[0].upcase != "PYTHON"
|
43
|
+
|
44
|
+
version = version[1].split(".")[0].to_i
|
45
|
+
return default if version >= 3
|
46
|
+
|
47
|
+
system_q("which python3") || default
|
48
|
+
rescue
|
49
|
+
return default
|
50
|
+
end
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
rescue
|
57
|
-
return default
|
58
|
-
end
|
59
|
-
def system_q command
|
60
|
-
IO.popen command, err: [:child, :out] do |f|
|
61
|
-
return f.gets
|
62
|
-
end
|
63
|
-
end
|
52
|
+
def system_q(command)
|
53
|
+
IO.popen(command, err: [:child, :out]) { |f| f.gets }
|
64
54
|
end
|
55
|
+
end
|
65
56
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/dist/include/ruby/engine.rb
CHANGED
@@ -1,62 +1,57 @@
|
|
1
1
|
require "gettc/types"
|
2
2
|
|
3
3
|
module Gettc
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
return "TArray.new(#{subtype.to_ruby})"
|
8
|
-
end
|
4
|
+
class Type
|
5
|
+
def to_ruby
|
6
|
+
return "TArray.new(#{subtype.to_ruby})" if self.is_a?(TArray)
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def dumb_ruby
|
30
|
-
if is_a? TArray then
|
31
|
-
return "[]"
|
32
|
-
end
|
8
|
+
case self
|
9
|
+
when TInt
|
10
|
+
"TInt"
|
11
|
+
when TLong
|
12
|
+
"TLong"
|
13
|
+
when TFloat
|
14
|
+
"TFloat"
|
15
|
+
when TDouble
|
16
|
+
"TDouble"
|
17
|
+
when TChar
|
18
|
+
"TChar"
|
19
|
+
when TString
|
20
|
+
"TString"
|
21
|
+
when TBoolean
|
22
|
+
"TBoolean"
|
23
|
+
else
|
24
|
+
"Object"
|
25
|
+
end
|
26
|
+
end
|
33
27
|
|
34
|
-
|
35
|
-
|
36
|
-
return "0"
|
37
|
-
when TChar
|
38
|
-
return "?$"
|
39
|
-
when TString
|
40
|
-
return '"$"'
|
41
|
-
when TBoolean
|
42
|
-
return "true"
|
43
|
-
end
|
28
|
+
def dumb_ruby
|
29
|
+
return "[]" if self.is_a?(TArray)
|
44
30
|
|
45
|
-
|
46
|
-
|
31
|
+
case self
|
32
|
+
when TInt, TLong, TFloat, TDouble
|
33
|
+
"0"
|
34
|
+
when TChar
|
35
|
+
"?$"
|
36
|
+
when TString
|
37
|
+
'"$"'
|
38
|
+
when TBoolean
|
39
|
+
"true"
|
40
|
+
else
|
41
|
+
"nil"
|
42
|
+
end
|
47
43
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
end
|
45
|
+
|
46
|
+
class RubyEngine
|
47
|
+
attr_reader :arglist, :input
|
48
|
+
|
49
|
+
def initialize(func, vars)
|
50
|
+
@arglist = vars.map(&:name).join(", ")
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@input = temp.join "\nreader.next()\n"
|
60
|
-
end
|
52
|
+
@input = vars.map do |var|
|
53
|
+
"#{var.name} = reader.next(#{var.type.to_ruby})"
|
54
|
+
end.join("\nreader.next()\n")
|
61
55
|
end
|
56
|
+
end
|
62
57
|
end
|
@@ -2,212 +2,224 @@ require "gettc/types"
|
|
2
2
|
include Gettc
|
3
3
|
|
4
4
|
module TopCoder
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
super message
|
20
|
-
end
|
5
|
+
class ParseError < StandardError
|
6
|
+
def initialize(text, pos, info = "")
|
7
|
+
message = text
|
8
|
+
|
9
|
+
if pos < text.size && pos >= 0
|
10
|
+
message = pos == 0 ? "" : text[0..(pos - 1)]
|
11
|
+
message << "|" << text[pos] << "|"
|
12
|
+
message << text[(pos + 1)..(-1)]
|
13
|
+
end
|
14
|
+
|
15
|
+
message = "<#{message}>"
|
16
|
+
message << " (#{info})" if info
|
17
|
+
|
18
|
+
super message
|
21
19
|
end
|
20
|
+
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
raise UnsupportedType.new typ
|
57
|
-
end
|
22
|
+
class Reader
|
23
|
+
def initialize(text)
|
24
|
+
raise ArgumentError.new("need a string to construct a Reader") unless text.is_a?(String)
|
25
|
+
@text = text
|
26
|
+
@pos = 0
|
27
|
+
@len = @text.size
|
28
|
+
end
|
29
|
+
|
30
|
+
def next(type = nil)
|
31
|
+
if type.nil?
|
32
|
+
spaces
|
33
|
+
expect(?,)
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
return next_array(type.subtype) if type.is_a?(TArray)
|
38
|
+
|
39
|
+
case type
|
40
|
+
when TBoolean
|
41
|
+
next_boolean
|
42
|
+
when TInt, TLong
|
43
|
+
next_int
|
44
|
+
when TFloat, TDouble
|
45
|
+
next_float
|
46
|
+
when TChar
|
47
|
+
next_char
|
48
|
+
when TString
|
49
|
+
next_string
|
50
|
+
else
|
51
|
+
raise UnsupportedType.new(type)
|
52
|
+
end
|
53
|
+
end
|
58
54
|
|
59
55
|
private
|
60
|
-
def raise_here message = nil
|
61
|
-
raise ParseError.new @text, @pos, message
|
62
|
-
end
|
63
|
-
def check_pos
|
64
|
-
if @pos >= @len
|
65
|
-
raise_here "unexpected end of input"
|
66
|
-
end
|
67
|
-
end
|
68
56
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
def spaces
|
74
|
-
while @pos < @len && @text[@pos] =~ /\s/ do
|
75
|
-
@pos += 1
|
76
|
-
end
|
77
|
-
end
|
78
|
-
def expect char
|
79
|
-
if token == char
|
80
|
-
@pos += 1
|
81
|
-
else
|
82
|
-
raise_here "expecting <#{char}>"
|
83
|
-
end
|
84
|
-
end
|
57
|
+
def raise_here(message = nil)
|
58
|
+
raise ParseError.new(@text, @pos, message)
|
59
|
+
end
|
85
60
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@pos += 4
|
90
|
-
return true
|
91
|
-
elsif @text[@pos, 5].upcase == "FALSE"
|
92
|
-
@pos += 5
|
93
|
-
return false
|
94
|
-
end
|
95
|
-
raise_here "expecting either true or false"
|
96
|
-
end
|
61
|
+
def check_pos
|
62
|
+
raise_here("unexpected end of input") if @pos >= @len
|
63
|
+
end
|
97
64
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
check_pos
|
103
|
-
if !is_digit
|
104
|
-
raise_here "expecting a digit"
|
105
|
-
end
|
106
|
-
start = @pos
|
107
|
-
while true do
|
108
|
-
@pos += 1
|
109
|
-
if @pos == @len || !is_digit
|
110
|
-
break
|
111
|
-
end
|
112
|
-
end
|
113
|
-
return @text[start..(@pos - 1)]
|
114
|
-
end
|
65
|
+
def token
|
66
|
+
check_pos
|
67
|
+
@text[@pos]
|
68
|
+
end
|
115
69
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if token == ?-
|
122
|
-
@pos += 1
|
123
|
-
return -next_positive_int
|
124
|
-
end
|
125
|
-
return next_positive_int
|
126
|
-
end
|
70
|
+
def spaces
|
71
|
+
while @pos < @len && @text[@pos] =~ /\s/ do
|
72
|
+
@pos += 1
|
73
|
+
end
|
74
|
+
end
|
127
75
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
136
|
-
return str.to_f
|
137
|
-
end
|
138
|
-
def next_float
|
139
|
-
spaces
|
140
|
-
if token == ?-
|
141
|
-
@pos += 1
|
142
|
-
return -next_positive_float
|
143
|
-
end
|
144
|
-
return next_positive_float
|
145
|
-
end
|
76
|
+
def expect(char)
|
77
|
+
if token == char
|
78
|
+
@pos += 1
|
79
|
+
else
|
80
|
+
raise_here("expecting <#{char}>")
|
81
|
+
end
|
82
|
+
end
|
146
83
|
|
147
|
-
|
148
|
-
|
149
|
-
char = token
|
150
|
-
if char == ?'
|
151
|
-
@pos += 1
|
152
|
-
ret = token
|
153
|
-
@pos += 1
|
154
|
-
expect ?'
|
155
|
-
return ret
|
156
|
-
end
|
157
|
-
@pos += 1
|
158
|
-
return char
|
159
|
-
end
|
84
|
+
def next_boolean
|
85
|
+
spaces
|
160
86
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
if token == ?"
|
170
|
-
@pos += 1
|
171
|
-
saved = @pos
|
172
|
-
spaces
|
173
|
-
if @pos == @len || @text[@pos] == ?, || @text[@pos] == ?]
|
174
|
-
@pos = saved
|
175
|
-
return @text[start..(@pos - 2)]
|
176
|
-
end
|
177
|
-
else
|
178
|
-
@pos += 1
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
87
|
+
if @text[@pos, 4].upcase == "TRUE"
|
88
|
+
@pos += 4
|
89
|
+
return true
|
90
|
+
elsif @text[@pos, 5].upcase == "FALSE"
|
91
|
+
@pos += 5
|
92
|
+
return false
|
93
|
+
end
|
182
94
|
|
183
|
-
|
184
|
-
|
185
|
-
char = token
|
186
|
-
case char
|
187
|
-
when ?]
|
188
|
-
@pos += 1
|
189
|
-
return
|
190
|
-
when ?,
|
191
|
-
@pos += 1
|
192
|
-
arr << self.next(elem_type)
|
193
|
-
next_elems elem_type, arr
|
194
|
-
else
|
195
|
-
raise_here "expecting either <,> or <]>"
|
196
|
-
end
|
197
|
-
end
|
95
|
+
raise_here("expecting either true or false")
|
96
|
+
end
|
198
97
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
98
|
+
def is_digit
|
99
|
+
@text[@pos] =~ /\d/
|
100
|
+
end
|
101
|
+
|
102
|
+
def next_digits
|
103
|
+
check_pos
|
104
|
+
raise_here("expecting a digit") unless is_digit
|
105
|
+
|
106
|
+
start = @pos
|
107
|
+
while true do
|
108
|
+
@pos += 1
|
109
|
+
break if @pos == @len || !is_digit
|
110
|
+
end
|
111
|
+
|
112
|
+
@text[start..(@pos - 1)]
|
113
|
+
end
|
114
|
+
|
115
|
+
def next_positive_int
|
116
|
+
next_digits.to_i
|
117
|
+
end
|
118
|
+
|
119
|
+
def next_int
|
120
|
+
spaces
|
121
|
+
|
122
|
+
if token == ?-
|
123
|
+
@pos += 1
|
124
|
+
return -next_positive_int
|
125
|
+
end
|
126
|
+
|
127
|
+
next_positive_int
|
128
|
+
end
|
129
|
+
|
130
|
+
def next_positive_float
|
131
|
+
str = next_digits
|
132
|
+
|
133
|
+
if @pos < @len
|
134
|
+
if @text[@pos] == ?.
|
135
|
+
@pos += 1
|
136
|
+
str << "." << next_digits
|
211
137
|
end
|
138
|
+
end
|
139
|
+
|
140
|
+
str.to_f
|
141
|
+
end
|
142
|
+
|
143
|
+
def next_float
|
144
|
+
spaces
|
145
|
+
|
146
|
+
if token == ?-
|
147
|
+
@pos += 1
|
148
|
+
return -next_positive_float
|
149
|
+
end
|
150
|
+
|
151
|
+
return next_positive_float
|
152
|
+
end
|
153
|
+
|
154
|
+
def next_char
|
155
|
+
spaces
|
156
|
+
char = token
|
157
|
+
|
158
|
+
if char == ?'
|
159
|
+
@pos += 1
|
160
|
+
ret = token
|
161
|
+
@pos += 1
|
162
|
+
expect(?')
|
163
|
+
return ret
|
164
|
+
end
|
165
|
+
|
166
|
+
@pos += 1
|
167
|
+
char
|
168
|
+
end
|
169
|
+
|
170
|
+
def next_string
|
171
|
+
spaces
|
172
|
+
expect(?")
|
173
|
+
start = @pos
|
174
|
+
while true do
|
175
|
+
raise_here("expecting a closing quote when reading a string") if @pos >= @len
|
176
|
+
if token == ?"
|
177
|
+
@pos += 1
|
178
|
+
saved = @pos
|
179
|
+
spaces
|
180
|
+
if @pos == @len || @text[@pos] == ?, || @text[@pos] == ?]
|
181
|
+
@pos = saved
|
182
|
+
return @text[start..(@pos - 2)]
|
183
|
+
end
|
184
|
+
else
|
185
|
+
@pos += 1
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def next_elems(elem_type, arr)
|
191
|
+
spaces
|
192
|
+
char = token
|
193
|
+
|
194
|
+
case char
|
195
|
+
when ?]
|
196
|
+
@pos += 1
|
197
|
+
return
|
198
|
+
when ?,
|
199
|
+
@pos += 1
|
200
|
+
arr << self.next(elem_type)
|
201
|
+
next_elems(elem_type, arr)
|
202
|
+
else
|
203
|
+
raise_here("expecting either <,> or <]>")
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def next_array(elem_type)
|
208
|
+
arr = []
|
209
|
+
|
210
|
+
spaces
|
211
|
+
expect(?[)
|
212
|
+
spaces
|
213
|
+
|
214
|
+
if token == ?]
|
215
|
+
@pos += 1
|
216
|
+
return arr
|
217
|
+
end
|
218
|
+
|
219
|
+
arr << self.next(elem_type)
|
220
|
+
next_elems(elem_type, arr)
|
221
|
+
|
222
|
+
arr
|
212
223
|
end
|
224
|
+
end
|
213
225
|
end
|