gettc 1.10 → 2.0
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/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
|