Skip to content

Commit ca95169

Browse files
committed
Feature: inside array for syntax
1 parent ae36010 commit ca95169

File tree

7 files changed

+373
-1
lines changed

7 files changed

+373
-1
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ exclude =
1717
ply
1818
nml/actions/action2var_variables.py
1919
nml/actions/action3_callbacks.py
20+
.venv

nml/ast/for_.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
__license__ = """
2+
NML is free software; you can redistribute it and/or modify
3+
it under the terms of the GNU General Public License as published by
4+
the Free Software Foundation; either version 2 of the License, or
5+
(at your option) any later version.
6+
7+
NML is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License along
13+
with NML; if not, write to the Free Software Foundation, Inc.,
14+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."""
15+
16+
from nml import expression, generic
17+
from nml.actions import action2layout
18+
from nml.ast import base_statement
19+
from nml.expression.array import Array
20+
21+
22+
class InArrayFor(base_statement.BaseStatement):
23+
def __init__(self, array, param, expressions, pos=None):
24+
base_statement.BaseStatement.__init__(self, "for", pos, False, False)
25+
self.array = array
26+
self.param = param
27+
self.expressions = expressions
28+
29+
def __str__(self):
30+
expressions_string = ""
31+
for expression in self.expressions:
32+
expressions_string += str(expression) + ', '
33+
expressions_string = expressions_string[:-2]
34+
return "[{} for {} in {}]".format(
35+
expressions_string, self.param, self.array,
36+
)
37+
38+
def reduce(self, id_dicts=None, unknown_id_fatal=True):
39+
self.array = self.array.reduce(id_dicts, unknown_id_fatal)
40+
out_list = []
41+
param_dict = {self.param.value : 0}
42+
id_dicts.append(param_dict)
43+
for value in self.array.values:
44+
param_dict[self.param.value] = value.value
45+
for expression in self.expressions:
46+
out_list.append(expression.reduce(id_dicts, unknown_id_fatal))
47+
id_dicts.remove(param_dict)
48+
return Array(out_list, self.pos)

nml/parser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
disable_item,
3030
error,
3131
font,
32+
for_,
3233
general,
3334
grf,
3435
item,
@@ -835,3 +836,7 @@ def p_tilelayout_item_prop(self, t):
835836
def p_constant(self, t):
836837
"constant : CONST expression EQ expression SEMICOLON"
837838
t[0] = constant.Constant(t[2], t[4])
839+
840+
def p_in_array_for(self, t):
841+
"""expression : LBRACKET non_empty_expression_list FOR ID IN expression RBRACKET"""
842+
t[0] = for_.InArrayFor(t[6], t[4], t[2], t.lineno(1))

nml/tokens.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"recolour_sprite": "RECOLOUR_SPRITE",
6262
"engine_override": "ENGINE_OVERRIDE",
6363
"sort": "SORT_VEHICLES",
64-
"const": "CONST"
64+
"const": "CONST",
65+
"for": "FOR",
66+
"in": "IN",
6567
}
6668
# fmt: on
6769

regression/042_for.nml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//Add action8, so we can test the vehicle in-game
2+
grf {
3+
grfid: "NML\42";
4+
name: string(STR_REGRESSION_NAME);
5+
desc: string(STR_REGRESSION_DESC);
6+
version: 0;
7+
min_compatible_version: 0;
8+
}
9+
10+
cargotable {
11+
COAL, LVST
12+
}
13+
14+
spriteset(station_spriteset, "station.png") {
15+
[ 1, 1, 5, 5, -2, -2]
16+
[ 7, 1, 5, 5, -2, -2]
17+
[ 2, 2, 3, 3, -1, -1]
18+
[ 8, 2, 3, 3, -1, -1]
19+
}
20+
21+
spritelayout station_sprite_layout_X(a) {
22+
ground {
23+
sprite: GROUNDSPRITE_RAIL_X;
24+
}
25+
building {
26+
sprite: 0x42E;
27+
xoffset: 0;
28+
yoffset: 0;
29+
zoffset: 0;
30+
xextent: 16;
31+
yextent: 5;
32+
zextent: 2;
33+
recolour_mode: RECOLOUR_REMAP;
34+
palette: PALETTE_USE_DEFAULT;
35+
}
36+
childsprite {
37+
sprite: DEFAULT(a);
38+
xoffset: 17;
39+
yoffset: 11;
40+
recolour_mode: RECOLOUR_REMAP;
41+
palette: PALETTE_USE_DEFAULT;
42+
}
43+
}
44+
45+
spritelayout station_sprite_layout_Y(a) {
46+
ground {
47+
sprite: GROUNDSPRITE_RAIL_Y;
48+
}
49+
building {
50+
sprite: 0x42F;
51+
xoffset: 0;
52+
yoffset: 0;
53+
zoffset: 0;
54+
xextent: 5;
55+
yextent: 16;
56+
zextent: 2;
57+
recolour_mode: RECOLOUR_REMAP;
58+
palette: PALETTE_USE_DEFAULT;
59+
}
60+
childsprite {
61+
sprite: station_spriteset(a);
62+
xoffset: 20;
63+
yoffset: 11;
64+
recolour_mode: RECOLOUR_REMAP;
65+
palette: PALETTE_USE_DEFAULT;
66+
}
67+
}
68+
69+
item (FEAT_STATIONS, basic_station, 255) {
70+
property {
71+
class : "TEST";
72+
classname: string(STR_STATION_TEST_CLASS);
73+
name : string(STR_STATION_BASIC);
74+
general_flags: bitmask(STAT_FLAG_EXTENDED_FOUNDATIONS);
75+
cargo_random_triggers: [LVST];
76+
disabled_platforms: bitmask(5, 6, 7, 8);
77+
tile_flags: [a | bitmask(a) for a in [0, 1, 2, 3]];
78+
station_layouts: [[[2]],[[a, a] for a in [4, 6]]];
79+
}
80+
graphics {
81+
foundations: 0;
82+
prepare_layout: [STORE_TEMP(0,nearby_tile_station_id(-1,2)), STORE_TEMP(1,1)];
83+
purchase_prepare_layout: STORE_TEMP(3,3);
84+
sprite_layouts: [
85+
station_sprite_layout_X(a),
86+
station_sprite_layout_Y(a) for a in [0, 1] + [2, 3]
87+
];
88+
anim_speed: company_colour1 + company_colour2;
89+
LVST: station_spriteset;
90+
COAL: station_spriteset;
91+
station_spriteset;
92+
}
93+
}

regression/expected/042_for.grf

1.32 KB
Binary file not shown.

regression/expected/042_for.nfo

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
// Automatically generated by GRFCODEC. Do not modify!
2+
// (Info version 32)
3+
// Escapes: 2+ 2- 2< 2> 2u< 2u> 2/ 2% 2u/ 2u% 2* 2& 2| 2^ 2sto = 2s 2rst = 2r 2psto 2ror = 2rot 2cmp 2ucmp 2<< 2u>> 2>>
4+
// Escapes: 71 70 7= 7! 7< 7> 7G 7g 7gG 7GG 7gg 7c 7C
5+
// Escapes: D= = DR D+ = DF D- = DC Du* = DM D* = DnF Du<< = DnC D<< = DO D& D| Du/ D/ Du% D%
6+
// Format: spritenum imagefile depth xpos ypos xsize ysize xrel yrel zoom flags
7+
8+
0 * 4 \d27
9+
10+
1 * 54 14 "C" "INFO"
11+
"B" "VRSN" \w4 \dx00000000
12+
"B" "MINV" \w4 \dx00000000
13+
"B" "NPAR" \w1 00
14+
"B" "PALS" \w1 "W"
15+
"B" "BLTR" \w1 "8"
16+
00
17+
00
18+
2 * 52 08 08 "NML\42" "NML regression test" 00 "A test newgrf testing NML" 00
19+
3 * 16 00 08 \b1 02 FF \wx0000
20+
09 "COAL" "LVST"
21+
22+
4 * 39 00 04 \b8 01 FF \wx00FF
23+
08 "TEST"
24+
13 18
25+
12 \dx00000002
26+
0C F0
27+
11 0B
28+
14 0E
29+
15 04
30+
0E \b1 \b1
31+
02
32+
\b2 \b2
33+
04 04
34+
06 06
35+
\b0 \b0
36+
37+
5 * 11 04 04 FF 01 \wxC4FF "Test" 00
38+
39+
6 * 20 04 04 FF 01 \wxC5FF "Basic station" 00
40+
41+
7 * 6 01 04 \b1 FF \wx0004
42+
43+
8 station.png 8bpp 1 1 5 5 -2 -2 normal
44+
9 station.png 8bpp 7 1 5 5 -2 -2 normal
45+
10 station.png 8bpp 2 2 3 3 -1 -1 normal
46+
11 station.png 8bpp 8 2 3 3 -1 -1 normal
47+
48+
// Name: station_spriteset - feature 04
49+
12 * 7 02 04 FF \b0 \b1
50+
51+
\w0
52+
53+
13 * 245 00 04 \b1 01 FF \wx00FF
54+
1A \b8
55+
\b66 \dx000003F4 \wx0000
56+
\dx0000842E \wx0000 \b0 \b0 \b0 \b16 \b5 \b2
57+
\dx8000842D \wx0002 \b17 \b11 80 88
58+
\b66 \dx000003F3 \wx0000
59+
\dx0000842F \wx0000 \b0 \b0 \b0 \b5 \b16 \b2
60+
\dx8000842D \wx0042 \b20 \b11 80 89 01
61+
\b66 \dx000003F4 \wx0000
62+
\dx0000842E \wx0000 \b0 \b0 \b0 \b16 \b5 \b2
63+
\dx8000842D \wx0002 \b17 \b11 80 8A
64+
\b66 \dx000003F3 \wx0000
65+
\dx0000842F \wx0000 \b0 \b0 \b0 \b5 \b16 \b2
66+
\dx8000842D \wx0042 \b20 \b11 80 8B 01
67+
\b66 \dx000003F4 \wx0000
68+
\dx0000842E \wx0000 \b0 \b0 \b0 \b16 \b5 \b2
69+
\dx8000842D \wx0002 \b17 \b11 80 8C
70+
\b66 \dx000003F3 \wx0000
71+
\dx0000842F \wx0000 \b0 \b0 \b0 \b5 \b16 \b2
72+
\dx8000842D \wx0042 \b20 \b11 80 8D 01
73+
\b66 \dx000003F4 \wx0000
74+
\dx0000842E \wx0000 \b0 \b0 \b0 \b16 \b5 \b2
75+
\dx8000842D \wx0002 \b17 \b11 80 8E
76+
\b66 \dx000003F3 \wx0000
77+
\dx0000842F \wx0000 \b0 \b0 \b0 \b5 \b16 \b2
78+
\dx8000842D \wx0042 \b20 \b11 80 8F 01
79+
80+
// Name: Station Layout@registers - Id FF
81+
// a : register 80
82+
// a : register 81
83+
// a : register 82
84+
// a : register 83
85+
// a : register 84
86+
// a : register 85
87+
// a : register 86
88+
// a : register 87
89+
14 * 238 02 04 FE 89
90+
1A 20 \dx00000000
91+
\2sto 1A 20 \dx00000080
92+
\2r 1A 20 \dx00000000
93+
\2sto 1A 20 \dx00000081
94+
\2r 1A 20 \dx00000001
95+
\2sto 1A 20 \dx00000082
96+
\2r 1A 20 \dx00000001
97+
\2sto 1A 20 \dx00000083
98+
\2r 1A 20 \dx00000002
99+
\2sto 1A 20 \dx00000084
100+
\2r 1A 20 \dx00000002
101+
\2sto 1A 20 \dx00000085
102+
\2r 1A 20 \dx00000003
103+
\2sto 1A 20 \dx00000086
104+
\2r 1A 20 \dx00000003
105+
\2sto 1A 20 \dx00000087
106+
\2r 7D 80 20 \dxFFFFFFFF // a
107+
\2sto 1A 20 \dx00000088
108+
\2r 7D 81 20 \dxFFFFFFFF // a
109+
\2sto 1A 20 \dx00000089
110+
\2r 7D 82 20 \dxFFFFFFFF // a
111+
\2sto 1A 20 \dx0000008A
112+
\2r 7D 83 20 \dxFFFFFFFF // a
113+
\2sto 1A 20 \dx0000008B
114+
\2r 7D 84 20 \dxFFFFFFFF // a
115+
\2sto 1A 20 \dx0000008C
116+
\2r 7D 85 20 \dxFFFFFFFF // a
117+
\2sto 1A 20 \dx0000008D
118+
\2r 7D 86 20 \dxFFFFFFFF // a
119+
\2sto 1A 20 \dx0000008E
120+
\2r 7D 87 20 \dxFFFFFFFF // a
121+
\2sto 1A 00 \dx0000008F
122+
\b0
123+
\wx8000 // Return computed value
124+
125+
// Name: Station Layout@prepare - Id FF
126+
15 * 35 02 04 FD 89
127+
1A 20 \dx00000000
128+
\2sto 6B 2F 20 \dx0000FFFF
129+
\2r 1A 20 \dx00000001
130+
\2sto 1A 00 \dx00000001
131+
\b0
132+
\wx8000 // Return computed value
133+
134+
// Name: @action3_0
135+
16 * 39 02 04 FC 89
136+
7E FD 20 \dxFFFFFFFF // Station Layout@prepare - Id FF
137+
\2r 7E FE 20 \dxFFFFFFFF // Station Layout@registers - Id FF
138+
\2r 10 00 \dx000000FF
139+
\b1
140+
\wx8000 \dx00000002 \dx00000002 // return 0;
141+
\wx00FF // station_spriteset;
142+
143+
// Name: @action3_1
144+
17 * 39 02 04 FB 89
145+
7E FD 20 \dxFFFFFFFF // Station Layout@prepare - Id FF
146+
\2r 7E FE 20 \dxFFFFFFFF // Station Layout@registers - Id FF
147+
\2r 10 00 \dx000000FF
148+
\b1
149+
\wx8000 \dx00000002 \dx00000002 // return 0;
150+
\wx00FF // station_spriteset;
151+
152+
// Name: @action3_2
153+
18 * 39 02 04 FD 89
154+
7E FD 20 \dxFFFFFFFF // Station Layout@prepare - Id FF
155+
\2r 7E FE 20 \dxFFFFFFFF // Station Layout@registers - Id FF
156+
\2r 10 00 \dx000000FF
157+
\b1
158+
\wx8000 \dx00000002 \dx00000002 // return 0;
159+
\wx00FF // station_spriteset;
160+
161+
// Name: @action3_3
162+
19 * 45 02 04 FF 89
163+
1A 20 \dx00000003
164+
\2sto 1A 20 \dx00000003
165+
\2r 7E FE 20 \dxFFFFFFFF // Station Layout@registers - Id FF
166+
\2r 10 00 \dx000000FF
167+
\b1
168+
\wx8000 \dx00000002 \dx00000002 // return 0;
169+
\wx00FF // station_spriteset;
170+
171+
20 * 9 00 04 \b1 01 FF \wx00FF
172+
0B 08
173+
174+
// Name: @return_action_0
175+
21 * 20 02 04 FE 89
176+
43 38 \dx0000000F
177+
\2+ 43 1C \dx0000000F
178+
\b0
179+
\wx8000 // Return computed value
180+
181+
// Name: @action3_4
182+
22 * 23 02 04 FE 89
183+
0C 00 \dx0000FFFF
184+
\b1
185+
\wx00FE \dx00000142 \dx00000142 // return (var[0x43, 24, 15] + var[0x43, 28, 15])
186+
\wx00FC // @action3_0;
187+
188+
// Name: @return_action_1
189+
23 * 20 02 04 FA 89
190+
43 38 \dx0000000F
191+
\2+ 43 1C \dx0000000F
192+
\b0
193+
\wx8000 // Return computed value
194+
195+
// Name: @action3_5
196+
24 * 33 02 04 FA 89
197+
0C 00 \dx0000FFFF
198+
\b2
199+
\wx00FB \dx00000000 \dx00000000 // @action3_1;
200+
\wx00FA \dx00000142 \dx00000142 // return (var[0x43, 24, 15] + var[0x43, 28, 15])
201+
\wx00FC // @action3_0;
202+
203+
// Name: @return_action_2
204+
25 * 20 02 04 FB 89
205+
43 38 \dx0000000F
206+
\2+ 43 1C \dx0000000F
207+
\b0
208+
\wx8000 // Return computed value
209+
210+
// Name: @action3_6
211+
26 * 33 02 04 FC 89
212+
0C 00 \dx0000FFFF
213+
\b2
214+
\wx00FD \dx00000000 \dx00000000 // @action3_2;
215+
\wx00FB \dx00000142 \dx00000142 // return (var[0x43, 24, 15] + var[0x43, 28, 15])
216+
\wx00FC // @action3_0;
217+
218+
27 * 18 03 04 01 FF \wx00FF \b3
219+
00 \wx00FA // @action3_5;
220+
01 \wx00FC // @action3_6;
221+
FF \wx00FF // @action3_3;
222+
\wx00FE // @action3_4;
223+

0 commit comments

Comments
 (0)