@@ -79,13 +79,19 @@ class parse {
79
79
std::string str;
80
80
size_t pos;
81
81
size_t max_pos;
82
- std::vector<codew> code ;
82
+ std::map<std::string, std:: vector<codew>> procs ;
83
83
std::map<std::string, int > vars;
84
84
std::map<std::string, int > labels;
85
85
std::vector<jump> jumps;
86
86
int label_num;
87
+ bool finalized;
88
+ std::vector<codew> *code;
87
89
88
- parse (): lvl(0 ), maxlvl(0 ), pos(0 ), max_pos(0 ), label_num(0 ) {}
90
+ parse ():
91
+ lvl (0 ), maxlvl(0 ), pos(0 ),
92
+ max_pos (0 ), label_num(0 ),
93
+ finalized (false ),
94
+ code (&procs[std::string()]) { }
89
95
90
96
std::string new_label ()
91
97
{
@@ -134,20 +140,20 @@ class parse {
134
140
135
141
saved_pos save ()
136
142
{
137
- return saved_pos{pos, code. size ()};
143
+ return saved_pos{pos, code-> size ()};
138
144
}
139
145
140
146
void restore (saved_pos s)
141
147
{
142
148
if ( pos > max_pos ) max_pos = pos;
143
149
pos = s.pos ;
144
- code. resize (s.opos );
150
+ code-> resize (s.opos );
145
151
}
146
152
147
153
codew remove_last ()
148
154
{
149
- codew ret = code. back ();
150
- code. pop_back ();
155
+ codew ret = code-> back ();
156
+ code-> pop_back ();
151
157
return ret;
152
158
}
153
159
void debug (const std::string &c)
@@ -251,29 +257,52 @@ class parse {
251
257
bool emit_word (std::string s)
252
258
{
253
259
codew c{ codew::word, s};
254
- code. push_back (c);
260
+ code-> push_back (c);
255
261
return true ;
256
262
}
257
263
bool emit_label (std::string s)
258
264
{
259
265
codew c{ codew::label, s};
260
- code. push_back (c);
266
+ code-> push_back (c);
261
267
return true ;
262
268
}
263
269
bool comment (std::string s)
264
270
{
265
271
codew c{ codew::comment, s};
266
- code. push_back (c);
272
+ code-> push_back (c);
267
273
return true ;
268
274
}
269
275
bool emit (std::string s)
270
276
{
271
277
codew c{ codew::byte, s};
272
278
if ( s.substr (0 ,4 ) == " TOK_" )
273
279
c.type = codew::tok;
274
- code. push_back (c);
280
+ code-> push_back (c);
275
281
return true ;
276
282
}
283
+ void push_proc (std::string l)
284
+ {
285
+ code = &procs[l];
286
+ }
287
+ void pop_proc (std::string l)
288
+ {
289
+ code = &procs[std::string ()];
290
+ }
291
+ std::vector<codew> &full_code ()
292
+ {
293
+ std::vector<codew> &p = procs[std::string ()];
294
+ if ( !finalized )
295
+ {
296
+ finalized = true ;
297
+ // Correctly terminate main code
298
+ if ( !p.size () || p.back ().type != codew::tok || p.back ().value != " TOK_END" )
299
+ p.push_back ({codew::tok, " TOK_END" });
300
+ for (auto &c: procs)
301
+ if ( !c.first .empty () )
302
+ p.insert (std::end (p), std::begin (c.second ), std::end (c.second ));
303
+ }
304
+ return p;
305
+ }
277
306
};
278
307
279
308
static VarType get_vartype (parse::codew cw)
@@ -482,7 +511,6 @@ static bool SMB_E_PUSH_LT(parse &s)
482
511
case LT_WHILE_2:
483
512
case LT_FOR_2:
484
513
case LT_IF:
485
- case LT_PROC_1:
486
514
case LT_DATA:
487
515
s.emit_word (l);
488
516
break ;
@@ -492,6 +520,11 @@ static bool SMB_E_PUSH_LT(parse &s)
492
520
case LT_PROC_2:
493
521
case LT_LAST_JUMP:
494
522
break ;
523
+ case LT_PROC_1:
524
+ // Optimize by switching codep
525
+ s.remove_last ();
526
+ s.push_proc (l);
527
+ break ;
495
528
}
496
529
return true ;
497
530
}
@@ -587,7 +620,7 @@ static bool SMB_E_POP_PROC_1(parse &s)
587
620
auto l = s.pop_loop (LT_PROC_1);
588
621
if ( l.empty () )
589
622
return false ;
590
- s.emit_label (l);
623
+ s.pop_proc (l);
591
624
return true ;
592
625
}
593
626
@@ -1117,13 +1150,13 @@ int main(int argc, char **argv)
1117
1150
1118
1151
s.emit (" TOK_END" );
1119
1152
// Optimize
1120
- peephole pp (s.code );
1153
+ peephole pp (s.full_code () );
1121
1154
// Statistics
1122
1155
if ( show_stats )
1123
- opstat op (s.code );
1156
+ opstat op (s.full_code () );
1124
1157
1125
1158
// Write global symbols
1126
- for (auto &c: s.code )
1159
+ for (auto &c: s.full_code () )
1127
1160
{
1128
1161
if ( c.type == parse::codew::word && c.value [0 ] >= ' A' && c.value [0 ] <= ' _' )
1129
1162
ofile << " \t .global " << c.value << " \n " ;
@@ -1147,7 +1180,7 @@ int main(int argc, char **argv)
1147
1180
" ;-----------------------------\n "
1148
1181
" ; Bytecode\n "
1149
1182
" bytecode_start:\n " ;
1150
- for (auto c: s.code )
1183
+ for (auto c: s.full_code () )
1151
1184
{
1152
1185
switch (c.type )
1153
1186
{
0 commit comments