depager 0.2.3 → 0.3.0.b20160729
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 +7 -0
- data/README.en +4 -19
- data/README.ja +42 -79
- data/bin/depager +42 -45
- data/examples/action_pl0d/pl0d.action.dr +421 -0
- data/examples/action_pl0d/test.pl0ds +49 -0
- data/examples/c89/c89.dr +493 -496
- data/examples/c89/test.c89 +10 -10
- data/examples/extension/astdf.rb +10 -0
- data/examples/extension/atree.dr +55 -0
- data/examples/{sample_calc → extension}/calc.atree.dr +42 -43
- data/examples/extension/calc.simple_action.dr +33 -0
- data/examples/extension/paction.dr +16 -15
- data/examples/extension/pactiontest.dr +14 -14
- data/examples/extension/simple_action.rb +44 -0
- data/examples/pl0d/pl0ds.dr +337 -334
- data/examples/pl0d/test.pl0ds +33 -33
- data/examples/rie_calc/calc.rie.dr +57 -0
- data/examples/rie_calc/test.calc +4 -0
- data/examples/rie_dcuse/dcuse.rie.dr +71 -0
- data/examples/rie_dcuse/test.dcuse +1 -0
- data/examples/rie_pl0/orig_ex/exerrdg.pl0 +44 -0
- data/examples/rie_pl0/orig_ex/exerrm.pl0 +19 -0
- data/examples/rie_pl0/orig_ex/exerrmre.pl0 +20 -0
- data/examples/rie_pl0/orig_ex/exerrtok.pl0 +18 -0
- data/examples/rie_pl0/orig_ex/exmdg.pl0 +40 -0
- data/examples/rie_pl0/orig_ex/exmdgwwl.pl0 +43 -0
- data/examples/rie_pl0/orig_ex/exmrw.pl0 +22 -0
- data/examples/rie_pl0/orig_ex/exmwwl.pl0 +18 -0
- data/examples/rie_pl0/orig_ex/exnorw.pl0 +17 -0
- data/examples/rie_pl0/pl0.rie.dr +450 -0
- data/examples/rie_pl0/test.pl0 +10 -0
- data/examples/sample_calc/calc.action.dr +33 -33
- data/examples/sample_calc/calc.ast.action.dr +65 -66
- data/examples/sample_calc/calc.ast.dr +55 -55
- data/examples/sample_calc/calc.cst.dr +45 -45
- data/examples/sample_calc/calc.dr +43 -43
- data/examples/sample_calc/calc.lex.dr +29 -29
- data/examples/sample_calc/{calc_prec.nvaction.dr → calc_prec.action.dr} +31 -31
- data/examples/slex_test/divreg.slex.dr +29 -29
- data/examples/slex_test/ljoin.slex.dr +36 -36
- data/examples/slex_test/test.divreg +1 -1
- data/examples/slex_test/test.ljoin +3 -3
- data/lib/depager.rb +582 -670
- data/lib/depager/grammar.rb +256 -291
- data/lib/depager/lr.rb +574 -579
- data/lib/depager/parser.rb +282 -277
- data/lib/depager/ruby/plugins/_rie_debug.rb +35 -0
- data/lib/depager/ruby/plugins/action.rb +53 -43
- data/lib/depager/ruby/plugins/ast.dr +364 -269
- data/lib/depager/ruby/plugins/ast.rb +1367 -1308
- data/lib/depager/ruby/plugins/cst.dr +172 -180
- data/lib/depager/ruby/plugins/cst.rb +587 -626
- data/lib/depager/ruby/plugins/lex.dr +85 -89
- data/lib/depager/ruby/plugins/lex.rb +310 -336
- data/lib/depager/ruby/plugins/rie.dr +723 -0
- data/lib/depager/ruby/plugins/rie.rb +1653 -0
- data/lib/depager/ruby/plugins/slex.dr +202 -200
- data/lib/depager/ruby/plugins/slex.rb +780 -817
- data/lib/depager/ruby/plugins/srp.rb +56 -51
- data/lib/depager/ruby/templates/extension_lalr_master.erb +46 -51
- data/lib/depager/ruby/templates/extension_lalr_slave.erb +99 -107
- data/lib/depager/ruby/templates/single_lalr_parser.erb +115 -117
- data/lib/depager/utils.rb +148 -318
- data/lib/depager/version.rb +4 -3
- metadata +52 -60
- data/ChangeLog +0 -16
- data/data/depager/pre-setup.rb +0 -3
- data/examples/c89/c89.tab.rb +0 -7127
- data/examples/pl0d/pl0ds.tab.rb +0 -2698
- data/examples/sample_calc/calc.action.tab.rb +0 -457
- data/examples/sample_calc/calc.ast.action.tab.rb +0 -749
- data/examples/sample_calc/calc.ast.tab.rb +0 -665
- data/examples/sample_calc/calc.astdf.dr +0 -54
- data/examples/sample_calc/calc.astdf.tab.rb +0 -672
- data/examples/sample_calc/calc.atree.tab.rb +0 -451
- data/examples/sample_calc/calc.cst.tab.rb +0 -644
- data/examples/sample_calc/calc.lex.tab.rb +0 -374
- data/examples/sample_calc/calc.nvaction.dr +0 -33
- data/examples/sample_calc/calc.nvaction.tab.rb +0 -465
- data/examples/sample_calc/calc.tab.rb +0 -365
- data/examples/sample_calc/calc_prec.nvaction.tab.rb +0 -431
- data/examples/slex_test/divreg.slex.tab.rb +0 -303
- data/examples/slex_test/ljoin.slex.tab.rb +0 -370
- data/lib/depager/ruby/plugins/_ast_tmpl.rb +0 -73
- data/lib/depager/ruby/plugins/astdf.rb +0 -6
- data/lib/depager/ruby/plugins/atree.dr +0 -55
- data/lib/depager/ruby/plugins/atree.rb +0 -347
- data/lib/depager/ruby/plugins/nvaction.rb +0 -19
- data/lib/depager/ruby/templates/simple.erb +0 -23
- data/setup.rb +0 -1585
@@ -0,0 +1,450 @@
|
|
1
|
+
%class Pl0::Parser
|
2
|
+
%extend Depager::Lexer ('plugins/lex.rb')
|
3
|
+
%extend Depager::Rie ('plugins/rie.rb')
|
4
|
+
#%decorate Depager::LALR::ShiftReducePrinter ('plugins/srp.rb')
|
5
|
+
%decorate @Rie
|
6
|
+
%inner{
|
7
|
+
KEYWORDS = {
|
8
|
+
"begin" => :BEGINN,
|
9
|
+
"end" => :END,
|
10
|
+
"call" => :CALL,
|
11
|
+
"const" => :CONST,
|
12
|
+
"do" => :DO,
|
13
|
+
"if" => :IF,
|
14
|
+
"then" => :THEN,
|
15
|
+
"odd" => :ODD,
|
16
|
+
"procedure" => :PROCEDURE,
|
17
|
+
"read" => :READ,
|
18
|
+
"writeln" => :WRITELN,
|
19
|
+
"write" => :WRITE,
|
20
|
+
"var" => :VAR,
|
21
|
+
"while" => :WHILE,
|
22
|
+
}
|
23
|
+
%}
|
24
|
+
%%
|
25
|
+
%LEX{
|
26
|
+
/\s+/, /\#.*/ { }
|
27
|
+
"<>" { yield token( '<>' ) }
|
28
|
+
"<=" { yield token( '<=' ) }
|
29
|
+
">=" { yield token( '>=' ) }
|
30
|
+
":=" { yield token( ':=' ) }
|
31
|
+
/\d+/ { yield token( :NUMBER, $&.to_i ) }
|
32
|
+
/\w+/ { yield token( KEYWORDS[$&] || :IDENT, $& ) }
|
33
|
+
/./ { yield token( $& ) }
|
34
|
+
%}
|
35
|
+
|
36
|
+
#begin-rule
|
37
|
+
program [ code ] :
|
38
|
+
block '.'
|
39
|
+
{
|
40
|
+
block._env = newenv()
|
41
|
+
block._lab = genlab()
|
42
|
+
$.code = block.code
|
43
|
+
exec_code(linearize_code($.code))
|
44
|
+
}
|
45
|
+
;
|
46
|
+
block [ _env, _lab, code ] :
|
47
|
+
constdefpart vardeclpart procdeclpart statement
|
48
|
+
{
|
49
|
+
%thread env
|
50
|
+
%except constdefpart._env = newenv( $._env )
|
51
|
+
$.code = [
|
52
|
+
[ :O_JMP, 0, $._lab ],
|
53
|
+
procdeclpart.code,
|
54
|
+
[ :O_LAB, 0, $._lab ],
|
55
|
+
[ :O_INT, 0, procdeclpart.env.nvars ],
|
56
|
+
statement.code,
|
57
|
+
[ :O_OPR, 0, :P_RET ]
|
58
|
+
]
|
59
|
+
debug_info "SYMS:\n" + procdeclpart.env.pretty_inspect
|
60
|
+
debug_info "CODE:\n" + $.code.pretty_inspect
|
61
|
+
}
|
62
|
+
;
|
63
|
+
constdefpart [ _env:eq, env ] :
|
64
|
+
# empty
|
65
|
+
{ %thread env }
|
66
|
+
| CONST constdeflist ';'
|
67
|
+
{ %thread env }
|
68
|
+
;
|
69
|
+
constdeflist [ _env:eq, env ] :
|
70
|
+
constdef
|
71
|
+
{ %thread env }
|
72
|
+
| constdeflist ',' constdef
|
73
|
+
{ %thread env }
|
74
|
+
;
|
75
|
+
constdef [ _env:eq, env ] :
|
76
|
+
IDENT '=' NUMBER
|
77
|
+
{
|
78
|
+
$.env = $._env | [ entry(:CONSTANT, IDENT.value, NUMBER.value) ]
|
79
|
+
not $._env[ IDENT.value ] or
|
80
|
+
message "redeclaration of constant '%s'", IDENT.value
|
81
|
+
}
|
82
|
+
;
|
83
|
+
vardeclpart [ _env:eq, env ] :
|
84
|
+
# empty
|
85
|
+
{ %thread env }
|
86
|
+
| VAR vardecllist ';'
|
87
|
+
{ %thread env }
|
88
|
+
;
|
89
|
+
vardecllist [ _env:eq, env ] :
|
90
|
+
vardecl
|
91
|
+
{ %thread env }
|
92
|
+
| vardecllist ',' vardecl
|
93
|
+
{ %thread env }
|
94
|
+
;
|
95
|
+
vardecl [ _env:eq, env ] :
|
96
|
+
IDENT
|
97
|
+
{
|
98
|
+
$.env = $._env | [ entry(:VARIABLE, IDENT.value, 0) ]
|
99
|
+
not $._env[ IDENT.value ] or
|
100
|
+
message "redeclaration of variable '%s'",IDENT.value
|
101
|
+
}
|
102
|
+
;
|
103
|
+
procdeclpart [ _env:eq, env, code ] :
|
104
|
+
# empty
|
105
|
+
{
|
106
|
+
%thread env
|
107
|
+
$.code = [ ]
|
108
|
+
}
|
109
|
+
| procdeclpart procdecl
|
110
|
+
{
|
111
|
+
%thread env
|
112
|
+
$.code = procdeclpart.code + procdecl.code
|
113
|
+
}
|
114
|
+
;
|
115
|
+
procdecl [ _env:eq, env, code ] :
|
116
|
+
prochead ';' block ';'
|
117
|
+
{
|
118
|
+
%thread env
|
119
|
+
%transfer code
|
120
|
+
block._lab = prochead.lab
|
121
|
+
}
|
122
|
+
;
|
123
|
+
prochead [ _env:eq, env, lab ] :
|
124
|
+
PROCEDURE IDENT
|
125
|
+
{
|
126
|
+
lab = genlab()
|
127
|
+
$.env = $._env | [ entry(:PROC, IDENT.value, lab) ]
|
128
|
+
$.lab = lab
|
129
|
+
not $._env[ IDENT.value ] or
|
130
|
+
message "redeclaration of procedure '%s'",IDENT.value
|
131
|
+
}
|
132
|
+
;
|
133
|
+
statement [ _env:eq, code ] :
|
134
|
+
# empty
|
135
|
+
{ $.code = []; }
|
136
|
+
| ident ':=' expression
|
137
|
+
{
|
138
|
+
%transfer _env
|
139
|
+
$.code = [
|
140
|
+
expression.code,
|
141
|
+
[ :O_STO, $._env.level - ident.entry.level, ident.entry.value ]
|
142
|
+
]
|
143
|
+
ident.entry.kind == :VARIABLE or
|
144
|
+
message "assignment to constant/procedure is not allowed"
|
145
|
+
}
|
146
|
+
| CALL ident
|
147
|
+
{
|
148
|
+
%transfer _env
|
149
|
+
$.code = [
|
150
|
+
[ :O_CAL, $._env.level - ident.entry.level, ident.entry.value ]
|
151
|
+
]
|
152
|
+
ident.entry.kind == :PROC or
|
153
|
+
message "call of a constant or a variable is meaningless"
|
154
|
+
}
|
155
|
+
| IF condition THEN statement
|
156
|
+
{
|
157
|
+
%transfer _env
|
158
|
+
lab = genlab();
|
159
|
+
$.code = [
|
160
|
+
condition.code,
|
161
|
+
[ :O_JPC, 0, lab ],
|
162
|
+
statement.code,
|
163
|
+
[ :O_LAB, 0, lab ]
|
164
|
+
]
|
165
|
+
}
|
166
|
+
| WHILE condition DO statement
|
167
|
+
{
|
168
|
+
%transfer _env
|
169
|
+
lab1 = genlab()
|
170
|
+
lab2 = genlab()
|
171
|
+
$.code = [
|
172
|
+
[ :O_LAB, 0, lab1 ],
|
173
|
+
condition.code,
|
174
|
+
[ :O_JPC, 0, lab2 ],
|
175
|
+
statement.code,
|
176
|
+
[ :O_JMP, 0, lab1 ],
|
177
|
+
[ :O_LAB, 0, lab2 ]
|
178
|
+
]
|
179
|
+
}
|
180
|
+
| WRITE '(' expression ')'
|
181
|
+
{
|
182
|
+
%transfer _env
|
183
|
+
$.code = [
|
184
|
+
expression.code,
|
185
|
+
[ :O_CSP, 0, :WRI ]
|
186
|
+
]
|
187
|
+
}
|
188
|
+
| WRITELN '(' expression ')'
|
189
|
+
{
|
190
|
+
%transfer _env
|
191
|
+
$.code = [
|
192
|
+
expression.code,
|
193
|
+
[ :O_CSP, 0, :WRI ],
|
194
|
+
[ :O_CSP, 0, :WRL ]
|
195
|
+
]
|
196
|
+
}
|
197
|
+
| WRITELN
|
198
|
+
{ $.code = [ [ :O_CSP, 0, :WRL ] ] }
|
199
|
+
| READ '(' ident ')'
|
200
|
+
{
|
201
|
+
%transfer _env
|
202
|
+
$.code = [
|
203
|
+
[ :O_CSP, 0, :RDI ],
|
204
|
+
[ :O_STO, $._env.level - ident.entry.level, ident.entry.value ]
|
205
|
+
]
|
206
|
+
ident.entry.kind == :VARIABLE or
|
207
|
+
message "read to constant/procedure is not allowed"
|
208
|
+
}
|
209
|
+
| BEGINN statementlist END
|
210
|
+
{ %transfer _env, code }
|
211
|
+
;
|
212
|
+
|
213
|
+
statementlist [ _env:eq, code ] :
|
214
|
+
statement
|
215
|
+
{ %transfer _env, code }
|
216
|
+
| statementlist ';' statement
|
217
|
+
{
|
218
|
+
%transfer _env
|
219
|
+
$.code = statementlist.code + [ statement.code ]
|
220
|
+
}
|
221
|
+
|
222
|
+
;
|
223
|
+
expression [ _env:eq, code ] :
|
224
|
+
term
|
225
|
+
{ %transfer _env, code }
|
226
|
+
| '+' term
|
227
|
+
{ %transfer _env, code }
|
228
|
+
| '-' term
|
229
|
+
{
|
230
|
+
%transfer _env
|
231
|
+
$.code = [
|
232
|
+
term.code,
|
233
|
+
[ :O_OPR, 0, :P_NEG ]
|
234
|
+
]
|
235
|
+
}
|
236
|
+
| expression addsub term
|
237
|
+
{
|
238
|
+
%transfer _env;
|
239
|
+
$.code = [
|
240
|
+
expression.code,
|
241
|
+
term.code,
|
242
|
+
addsub.code
|
243
|
+
]
|
244
|
+
}
|
245
|
+
;
|
246
|
+
addsub [ code ] :
|
247
|
+
'+' { $.code = [ :O_OPR, 0, :P_ADD ] }
|
248
|
+
| '-' { $.code = [ :O_OPR, 0, :P_SUB ] }
|
249
|
+
;
|
250
|
+
term [ _env:eq, code ] :
|
251
|
+
factor
|
252
|
+
{ %transfer _env, code }
|
253
|
+
| term muldiv factor
|
254
|
+
{
|
255
|
+
%transfer _env
|
256
|
+
$.code = [
|
257
|
+
term.code,
|
258
|
+
factor.code,
|
259
|
+
muldiv.code
|
260
|
+
]
|
261
|
+
}
|
262
|
+
;
|
263
|
+
muldiv [ code ] :
|
264
|
+
'*' { $.code = [ :O_OPR, 0, :P_MUL ] }
|
265
|
+
| '/' { $.code = [ :O_OPR, 0, :P_DIV ] }
|
266
|
+
;
|
267
|
+
factor [ _env:eq, code ] :
|
268
|
+
ident
|
269
|
+
{
|
270
|
+
%transfer _env
|
271
|
+
$.code = ident.entry.kind == :CONSTANT ?
|
272
|
+
[ :O_LIT, 0, ident.entry.value ] :
|
273
|
+
[ :O_LOD, $._env.level - ident.entry.level, ident.entry.value ]
|
274
|
+
ident.entry.kind != :PROC or
|
275
|
+
message "expression must not contain a procedure identifier"
|
276
|
+
}
|
277
|
+
| NUMBER
|
278
|
+
{ $.code = [ :O_LIT, 0, NUMBER.value ] }
|
279
|
+
| '(' expression ')'
|
280
|
+
{ %transfer _env, code }
|
281
|
+
;
|
282
|
+
|
283
|
+
condition [ _env:eq, code ] :
|
284
|
+
ODD expression
|
285
|
+
{
|
286
|
+
%transfer _env
|
287
|
+
$.code = [
|
288
|
+
expression.code,
|
289
|
+
[ :O_OPR, 0, :P_ODD ]
|
290
|
+
]
|
291
|
+
}
|
292
|
+
| expression-left relop expression-right
|
293
|
+
{
|
294
|
+
%transfer _env
|
295
|
+
$.code = [
|
296
|
+
left.code,
|
297
|
+
right.code,
|
298
|
+
relop.code
|
299
|
+
]
|
300
|
+
}
|
301
|
+
;
|
302
|
+
relop [ code ] :
|
303
|
+
'=' { $.code = [ :O_OPR, 0, :P_EQ ] }
|
304
|
+
| '<>' { $.code = [ :O_OPR, 0, :P_NE ] }
|
305
|
+
| '<' { $.code = [ :O_OPR, 0, :P_LT ] }
|
306
|
+
| '>' { $.code = [ :O_OPR, 0, :P_GT ] }
|
307
|
+
| '<=' { $.code = [ :O_OPR, 0, :P_LE ] }
|
308
|
+
| '>=' { $.code = [ :O_OPR, 0, :P_GE ] }
|
309
|
+
;
|
310
|
+
ident [ _env:eq, entry ] :
|
311
|
+
IDENT
|
312
|
+
{
|
313
|
+
$.entry = $._env[ IDENT.value ]
|
314
|
+
$._env[ IDENT.value ] or
|
315
|
+
message "undeclared identifier %s", IDENT.value
|
316
|
+
}
|
317
|
+
;
|
318
|
+
#end-rule
|
319
|
+
%%
|
320
|
+
class Pl0::Rie
|
321
|
+
class Env
|
322
|
+
attr_reader :ary, :level
|
323
|
+
def initialize ary, level = 0
|
324
|
+
@ary, @level = ary, level
|
325
|
+
# warn self.inspect
|
326
|
+
end
|
327
|
+
def nvars
|
328
|
+
@ary.inject(0){|r, i| i.level == level and i.kind == :VARIABLE and r += 1 ; r }
|
329
|
+
end
|
330
|
+
def | ary
|
331
|
+
x = @ary.find_all{|i| i.level == level and i.kind == :VARIABLE }.size+3
|
332
|
+
arg = @ary.dup
|
333
|
+
ary.each do |i|
|
334
|
+
i.level = level
|
335
|
+
if i.kind == :VARIABLE
|
336
|
+
i.value = x
|
337
|
+
x += 1
|
338
|
+
end
|
339
|
+
arg.delete_if{|j| j.name == i.name}
|
340
|
+
arg << i
|
341
|
+
end
|
342
|
+
Env.new(arg, level)
|
343
|
+
end
|
344
|
+
def [] name
|
345
|
+
@ary.find{|i| i.name == name }
|
346
|
+
end
|
347
|
+
def inspect
|
348
|
+
"[#{@level}|#{@ary.inspect}]"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
def newenv arg = nil
|
352
|
+
arg ? Env.new(arg.ary.dup, arg.level+1) : Env.new([])
|
353
|
+
end
|
354
|
+
def genlab
|
355
|
+
@label ||= 0
|
356
|
+
@label += 1
|
357
|
+
end
|
358
|
+
class Entry
|
359
|
+
attr_accessor :kind, :name, :value, :level
|
360
|
+
def initialize k, n, v
|
361
|
+
@kind, @name, @value = k, n, v
|
362
|
+
@level = nil
|
363
|
+
end
|
364
|
+
def inspect
|
365
|
+
"(#{@name}.#{@level}:#{@kind.to_s[0,1]}/#{@value})"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
def entry k, n, v
|
369
|
+
#warn "ENTRY:#{n}:#{v.inspect}"
|
370
|
+
Entry.new(k, n, v)
|
371
|
+
end
|
372
|
+
def message *args
|
373
|
+
print("#{basis.file.lineno}:")
|
374
|
+
printf(*args); puts "\n"; exit
|
375
|
+
end
|
376
|
+
|
377
|
+
def debug_info *args
|
378
|
+
$DEBUG and warn(sprintf(*args))
|
379
|
+
end
|
380
|
+
def linearize_code code, res=[], labs={}
|
381
|
+
code.each do |i|
|
382
|
+
case i[0]
|
383
|
+
when :O_LAB
|
384
|
+
lab, addr = i[2], res.size
|
385
|
+
debug_info "PATCH: #{lab}->#{addr} @ #{labs[lab].inspect}"
|
386
|
+
labs[lab] and labs[lab].each{|i| res[i][2] = addr }
|
387
|
+
labs[lab] = res.size
|
388
|
+
when :O_JMP, :O_JPC, :O_CAL
|
389
|
+
lab, addr = i[2], labs[i[2]]
|
390
|
+
if addr.is_a? Integer
|
391
|
+
i[2] = addr
|
392
|
+
else
|
393
|
+
labs[lab] ||= []
|
394
|
+
labs[lab] << res.size
|
395
|
+
end
|
396
|
+
res << i
|
397
|
+
when Symbol
|
398
|
+
res << i
|
399
|
+
else
|
400
|
+
linearize_code i, res, labs
|
401
|
+
end
|
402
|
+
end ; res
|
403
|
+
end
|
404
|
+
# :-3(BP) :-2 :-1 *STACK*
|
405
|
+
# [lexical base][caller base][PC]{...vars...}
|
406
|
+
def exec_code ils
|
407
|
+
warn "\n** CODE **"
|
408
|
+
ils.each_with_index{|i,x| warn "#{'% 4i'%x} #{i.inspect}"}
|
409
|
+
warn "\n** EXEC **"
|
410
|
+
pc, bp, s = 0, 1, [0, 0, 0, 0]
|
411
|
+
begin
|
412
|
+
op, l, a = ils[pc] ; pc += 1
|
413
|
+
debug_info " #{s.inspect}\nPC:#{pc-1} BP:#{bp} CODE:[#{op}, #{l}, #{a}]"
|
414
|
+
case op
|
415
|
+
when :O_LIT ; s.push a
|
416
|
+
when :O_OPR ;
|
417
|
+
case a
|
418
|
+
when :P_RET; _, bp, pc, = s.slice!(bp, s.size-1)
|
419
|
+
when :P_NEG; s.push(-s.pop)
|
420
|
+
when :P_ODD; s.push s.pop % 2
|
421
|
+
when :P_ADD; r=s.pop; s.push s.pop + r
|
422
|
+
when :P_SUB; r=s.pop; s.push s.pop - r
|
423
|
+
when :P_MUL; r=s.pop; s.push s.pop * r
|
424
|
+
when :P_DIV; r=s.pop; s.push s.pop / r
|
425
|
+
when :P_EQ ; r=s.pop; s.push( s.pop == r ? 1 : 0 )
|
426
|
+
when :P_NE ; r=s.pop; s.push( s.pop != r ? 1 : 0 )
|
427
|
+
when :P_LT ; r=s.pop; s.push( s.pop < r ? 1 : 0 )
|
428
|
+
when :P_GE ; r=s.pop; s.push( s.pop >= r ? 1 : 0 )
|
429
|
+
when :P_GT ; r=s.pop; s.push( s.pop > r ? 1 : 0 )
|
430
|
+
when :P_LE ; r=s.pop; s.push( s.pop <= r ? 1 : 0 )
|
431
|
+
end
|
432
|
+
when :O_LOD; x=bp;l.times{x=s[x]}; s.push s[x+a];
|
433
|
+
when :O_STO; x=bp;l.times{x=s[x]}; s[x+a] = s.pop;
|
434
|
+
when :O_CAL; x=bp;l.times{x=s[x]}; s.push x, bp, pc; bp, pc = s.size-3, a;
|
435
|
+
when :O_INT; s.fill(0, s.size, a)
|
436
|
+
when :O_JMP; pc = a
|
437
|
+
when :O_JPC; pc = a if s.pop == 0
|
438
|
+
when :O_CSP;
|
439
|
+
case a
|
440
|
+
when :RDI; print "?"; s.push Integer(STDIN.gets)
|
441
|
+
when :WRI; printf( "\t%10d", s.pop )
|
442
|
+
when :WRL; puts ""
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end while pc != 0
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
parser = Pl0.create_decorated_parser
|
450
|
+
r, = parser.parse(ARGF)
|