Class: Sexpir::Parser

Inherits:
Object
  • Object
show all
Includes:
Log
Defined in:
lib/sexpir/parser.rb

Constant Summary collapse

OP_TRANSLATE =
{
  "gt" => ">",
  "lt" => "<",
  "eq" => "=",
  "neq"=> "/=",
  "gte"=> ">=",
  "lte"=> "<=",
}
NORMALIZED_OP =
{
  "*"  => "mul",
  "+"  => "add",
  "-"  => "sub",
  "/"  => "div",
  "="  => "eq",
  ">=" => "gte",
  "<=" => "lte",
  "/=" => "neq"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Log

#indent, #log, #log_dbg, #step

Constructor Details

#initializeParser

Returns a new instance of Parser.



13
14
15
16
# File 'lib/sexpir/parser.rb', line 13

def initialize
  @type_table={}
  @var_table ={}
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



11
12
13
# File 'lib/sexpir/parser.rb', line 11

def options
  @options
end

Instance Method Details

#expect(sexp, klass, value = nil) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/sexpir/parser.rb', line 54

def expect sexp,klass,value=nil
  unless (kind=sexp.shift).is_a? klass
    log "ERROR : expecting a #{klass}. Got a #{kind}."
    raise "Syntax error"
  end
  if value
    unless value==kind
      log "ERROR : expecting value '#{value}'. Got '#{kind}'"
      raise "Syntax error"
    end
  end
  return kind
end

#objectify(sexp) ⇒ Object



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
# File 'lib/sexpir/parser.rb', line 24

def objectify sexp
  circ=Circuit.new
  sexp.shift
  circ.name=sexp.shift
  while sexp.any?
    s=sexp.shift
    case s.first
    when :signal
      circ.signals << parse_signal(s)
    when :input
      circ.inputs << parse_input(s)
    when :output
      circ.outputs << parse_output(s)
    when :assign
      circ.body << parse_assign(s)
    when :component
      circ.body << parse_component(s)
    when :connect
      circ.body << parse_connect(s)
    when :comb,:combinatorial
      circ.body << parse_comb(s)
    when :seq,:sync,:sequential
      circ.body << parse_seq(s)
    else
      raise "unknown car #{s}"
    end
  end
  circ
end

#parse(sexpfile) ⇒ Object



18
19
20
21
22
# File 'lib/sexpir/parser.rb', line 18

def parse sexpfile
  log "[+] parsing  '#{sexpfile}'"
  sexp=SXP.read IO.read(sexpfile)
  ast=objectify(sexp)
end

#parse_assign(sexp) ⇒ Object



264
265
266
267
268
269
270
# File 'lib/sexpir/parser.rb', line 264

def parse_assign sexp
  assign=Assign.new
  sexp.shift
  assign.lhs=parse_expression(sexp.shift)
  assign.rhs=parse_expression(sexp.shift)
  assign
end

#parse_binary(sexp) ⇒ Object



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/sexpir/parser.rb', line 360

def parse_binary sexp
  case sexp.first
  when :mread
    ret=MRead.new
    sexp.shift
    ret.mem = Mem.new(sexp.shift) # memory name
    ret.addr= parse_expression(sexp.shift)
  else
    ret=Binary.new
    ret.op=sexp.shift
    #ret.op=OP_TRANSLATE[ret.op.to_s]||ret.op.to_s
    ret.op=NORMALIZED_OP[ret.op.to_s] || ret.op.to_s
    ret.lhs=parse_expression(sexp.shift)
    ret.rhs=parse_expression(sexp.shift)
  end
  ret
end

#parse_body(sexp) ⇒ Object



219
220
221
222
223
224
225
# File 'lib/sexpir/parser.rb', line 219

def parse_body sexp
  body=Body.new
  while sexp.any?
     body << parse_statement(sexp.shift)
  end
  body
end

#parse_case(sexp) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/sexpir/parser.rb', line 272

def parse_case sexp
  ret=Case.new
  sexp.shift
  ret.expr=parse_expression(sexp.shift)
  while sexp.any?
    ary=sexp.shift
    case ary.first
    when :when
      ret.whens << parse_when(ary)
    when :default
      ret.default=parse_default(ary)
    else
      raise "unknown case alternative : '#{ary.first}'"
    end
  end

  ret
end

#parse_comb(sexp) ⇒ Object



203
204
205
206
207
208
209
# File 'lib/sexpir/parser.rb', line 203

def parse_comb sexp
  comb=Combinatorial.new
  sexp.shift
  label=sexp.shift
  comb.body=parse_body(sexp)
  comb
end

#parse_component(sexp) ⇒ Object

components stuff =====


160
161
162
163
164
165
166
# File 'lib/sexpir/parser.rb', line 160

def parse_component sexp
  comp=Component.new
  sexp.shift
  comp.name=sexp.shift
  comp.type=sexp.shift
  comp
end

#parse_connect(sexp) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/sexpir/parser.rb', line 168

def parse_connect sexp
  con=Connect.new
  sexp.shift
  con.source=parse_port(sexp.shift)
  con.sink  =parse_port(sexp.shift)
  con
end

#parse_default(sexp) ⇒ Object



299
300
301
302
303
304
# File 'lib/sexpir/parser.rb', line 299

def parse_default sexp
  ret=Default.new
  sexp.shift
  ret.body=parse_body(sexp)
  ret
end

#parse_else(sexp) ⇒ Object



258
259
260
261
262
# File 'lib/sexpir/parser.rb', line 258

def parse_else sexp
  sexp.shift
  body=parse_body(sexp)
  body
end

#parse_elsif(sexp) ⇒ Object



252
253
254
255
256
# File 'lib/sexpir/parser.rb', line 252

def parse_elsif sexp
  sexp.shift
  body=parse_body(sexp)
  body
end

#parse_expression(sexp) ⇒ Object

expressions



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/sexpir/parser.rb', line 308

def parse_expression sexp
  case sexp
  when Array
    case sexp.size
    when 1
      case sexp
      when Symbol
        return Var.new(sexp)
      when Integer
        return Const.new(sexp)
      else
        raise "unknown expression '#{sexp}'"
      end
    when 2
      ret=parse_unary(sexp)
    when 3
      ret=parse_binary(sexp)
    when 4
      ret=parse_slice(sexp)
    else
      raise "unknown expression '#{sexp}'(size = '#{sexp.size}')"
    end
  when Symbol
    ret=Var.new(sexp)
  when Integer
    ret=Const.new(sexp)
  else
    raise "unknown expression '#{sexp}'"
  end
  ret
end

#parse_if(sexp) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/sexpir/parser.rb', line 227

def parse_if sexp
  if_=If.new
  sexp.shift
  if_.cond = parse_expression(sexp.shift)
  while sexp.any?
    case sexp.first.first
    when :then
      if_.then = parse_then(sexp.shift)
    when :elsif
      if_.elsifs << parse_elsif(sexp.shift)
    when :else
      if_.else = parse_else(sexp.shift)
    else
      raise "error parsing 'if' : #{sexp.first.first}"
    end
  end
  if_
end

#parse_input(sexp) ⇒ Object



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
# File 'lib/sexpir/parser.rb', line 99

def parse_input sexp
  input=Input.new
  sexp.shift
  input.name=sexp.shift
  case sexp.first
  when Symbol
    input.type=sexp.shift
  when Integer
    val=sexp.shift
    input.type="bv#{val}"
  end
  while sexp.any?
    case sexp.first
    when Array
      ary=sexp.shift
      field_name=ary.shift
      case field_name
      when :bits_sign,:name,:reset,:reset_less,:name_override,:min,:max
        input.send("#{field_name}=",ary.shift)
      else
        raise "unknow signal attribut '#{field_name}'"
      end
    else
      raise "unknown signal attribute '#{sexpr.first}'"
    end
  end
  input
end

#parse_output(sexp) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/sexpir/parser.rb', line 128

def parse_output sexp
  output=Output.new
  sexp.shift
  output.name=sexp.shift
  case sexp.first
  when Symbol
    output.type=sexp.shift
  when Integer
    val=sexp.shift
    output.type="bv#{val}"
  end
  while sexp.any?
    case sexp.first
    when Array
      ary=sexp.shift
      field_name=ary.shift
      case field_name
      when :bits_sign,:name,:reset,:reset_less,:name_override,:min,:max
        output.send("#{field_name}=",ary.shift)
      else
        raise "unknow signal attribut '#{field_name}'"
      end
    else
      raise "unknown signal attribute '#{sexpr.first}'"
    end
  end
  output
end

#parse_port(sexp) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/sexpir/parser.rb', line 176

def parse_port sexp
  case sexp
  when Array
    port=Port.new
    sexp.shift
    port.component_name=sexp.shift
    port.name=sexp.shift
    return port
  else
    return sexp
  end
end

#parse_seq(sexp) ⇒ Object



211
212
213
214
215
216
217
# File 'lib/sexpir/parser.rb', line 211

def parse_seq sexp
  comb=Sequential.new
  sexp.shift
  label=sexp.shift
  comb.body=parse_body(sexp)
  comb
end

#parse_signal(sexp) ⇒ Object

IO & Signals ===========


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
# File 'lib/sexpir/parser.rb', line 69

def parse_signal sexp
  sig=Signal.new
  sexp.shift
  sig.name=sexp.shift
  case sexp.first
  when Symbol
    sig.type=sexp.shift
  when Integer
    val=sexp.shift
    sig.type="bv#{val}"
  end
  while sexp.any?
    case sexp.first
    when Array
      ary=sexp.shift
      field_name=ary.shift
      case field_name
      when :bits_sign,:name,:reset,:reset_less,:name_override,:min,:max
        sig.send("#{field_name}=",ary.shift)
      else
        raise "unknow signal attribut '#{field_name}'"
      end
    else
      raise "unknown signal attribute '#{sexpr.first}'"
    end
  end

  sig
end

#parse_slice(sexp) ⇒ Object



384
385
386
387
388
389
390
391
# File 'lib/sexpir/parser.rb', line 384

def parse_slice sexp
  ret=Slice.new
  sexp.shift
  ret.expr=parse_expression(sexp.shift)
  ret.msb=parse_expression(sexp.shift)
  ret.lsb=parse_expression(sexp.shift)
  ret
end

#parse_statement(sexp) ⇒ Object

statements



190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/sexpir/parser.rb', line 190

def parse_statement sexp
  case sexp.first
  when :if
    parse_if(sexp)
  when :assign
    parse_assign(sexp)
  when :case
    parse_case(sexp)
  else
    raise "unknow statement starting with : #{sexp.first}"
  end
end

#parse_then(sexp) ⇒ Object



246
247
248
249
250
# File 'lib/sexpir/parser.rb', line 246

def parse_then sexp
  sexp.shift
  body=parse_body(sexp)
  body
end

#parse_unary(sexp) ⇒ Object



378
379
380
381
382
# File 'lib/sexpir/parser.rb', line 378

def parse_unary sexp
  ret=Unary.new
  ret.op=sexp.shift
  ret
end

#parse_when(sexp) ⇒ Object



291
292
293
294
295
296
297
# File 'lib/sexpir/parser.rb', line 291

def parse_when sexp
  ret=When.new
  sexp.shift
  ret.expr=parse_expression(sexp.shift)
  ret.body=parse_body(sexp)
  ret
end