-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtrans.rb
More file actions
143 lines (112 loc) · 2.21 KB
/
Copy pathtrans.rb
File metadata and controls
143 lines (112 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
require 'pry'
######### Memory management
class Mem
def initialize
@data = ""
@layout = {}
end
def create_ws ws
ws.mem_index = @data.size
@layout[ws.name ]= ws
@data << (" " * ws.size)
if ws.value != nil
self[ws.name] = ws.value
end
if ws.children.size != 0
ws.children.each do |c|
create_ws c
end
end
end
def real_size ws
return ws.size if ws.size != 0
s = 0
ws.children.each do |c|
s += real_size( c )
end
s
end
def [] (name)
c = @layout[name]
@data[c.mem_index, real_size(c)]
end
def []=(name,val)
c = @layout[name]
size = real_size(c)
val += " " * size
(0...size).each do |n|
@data[c.mem_index+n] = val[n]
end
end
end
class WS
attr_accessor :mem_index, :children, :PIC, :name, :value, :size
def initialize( params = {} )
@pic = params[:PIC]
@size = calc_size @pic
@name = params[:name]
@children = params[:children] || []
@value = params[:value]
end
def calc_size pic
return 0 if pic == nil
pic.match(/X\((\d+)\)/)[1].to_i
end
end
########### DSL
def WORK_STORAGE(arg, &block)
def ws(name, params = {}, &child)
params[:name] = name
if child != nil
params[:children] = [*child.call]
end
WS.new( params )
end
@mem = Mem.new
elems = block.call
elems = [elems] if !elems.is_a? Array
elems.each { |ws| @mem.create_ws( ws ) }
end
def PROCEDURE(arg, &block)
def DISPLAY arg
if arg.is_a? Symbol
res = @mem[arg]
else
res = arg
end
puts res
end
def MOVE arg, params = {}
if arg.is_a? Symbol
res = @mem[arg]
else
res = arg
end
@mem[params[:to]] = arg
end
def ACCEPT arg, params = {}
if arg.is_a? Symbol
@mem[arg] = gets
end
end
def STRING
end
block.call
end
# Example
WORK_STORAGE :SECTION do
[ws( :CONTEXT ) {[
ws( :NAME, :PIC => "X(10)" ),
ws( :ADDRESS ) {[
ws( :ADDRESS1, :PIC => "X(10)" ),
ws( :ADDRESS2, :PIC => "X(10)" ),
ws( :ADDRESS3, :PIC => "X(10)" ),
ws( :POSTCODE, :PIC => "X(10)" )
]}
]}]
end
PROCEDURE :DIVISION do
DISPLAY "What is your name? "
ACCEPT :NAME
DISPLAY :CONTEXT
end