Module: Minjs::Lex::Statement

Includes:
Minjs
Included in:
Parser
Defined in:
lib/minjs/lex/statement.rb

Overview

12

Constant Summary

Constants included from Minjs

VERSION

Instance Method Summary collapse

Instance Method Details

#block(var_env) ⇒ Object

Tests next literals sequence is Block or not.

See Also:



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/minjs/lex/statement.rb', line 58

def block(var_env)
  pos0 = pos
  return nil unless eql_lit?(ECMA262::PUNC_LCURLYBRAC)
  if eql_lit?(ECMA262::PUNC_RCURLYBRAC)
    return ECMA262::StBlock.new(ECMA262::StatementList.new([]))
  end

  if s = statement_list(var_env) and eql_lit?(ECMA262::PUNC_RCURLYBRAC)
    ECMA262::StBlock.new(s)
  else
    raise ParseError.new('no "}" end of block', lex)
  end
end

#break_statement(var_env) ⇒ Object

Tests next literals sequence is BreakStatement or not.

See Also:



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/minjs/lex/statement.rb', line 319

def break_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_BREAK)

  if semicolon(var_env)
    ECMA262::StBreak.new
  elsif e=identifier(var_env) and semicolon(var_env)
    ECMA262::StBreak.new(e)
  else
    if e
      raise ParseError.new("no semicolon at end of break statement", self)
    else
      raise ParseError.new("unexpected token", self)
    end
  end
end

#continue_statement(var_env) ⇒ Object

Tests next literals sequence is ContinueStatement or not.

See Also:



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/minjs/lex/statement.rb', line 300

def continue_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_CONTINUE)

  if semicolon(var_env)
    ECMA262::StContinue.new
  elsif e=identifier(var_env) and semicolon(var_env)
    ECMA262::StContinue.new(e)
  else
    if e
      raise ParseError.new("no semicolon at end of continue statement", self)
    else
      raise ParseError.new("unexpected token", self)
    end
  end
end

#debugger_statement(var_env) ⇒ Object

Tests next literals sequence is DebuggerStatement or not.

See Also:



479
480
481
482
483
484
485
486
# File 'lib/minjs/lex/statement.rb', line 479

def debugger_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_DEBUGGER)
  if semicolon(var_env)
    ECMA262::StDebugger.new
  else
    raise ParseError.new("no semicolon at end of debugger statement", self)
  end
end

#empty_statement(var_env) ⇒ Object

Tests next literals sequence is EmptyStatement or not.

See Also:



152
153
154
155
156
157
158
159
160
# File 'lib/minjs/lex/statement.rb', line 152

def empty_statement(var_env)
  a = peek_lit(nil)
  if a == ECMA262::PUNC_SEMICOLON
    fwd_after_peek
    ECMA262::StEmpty.new
  else
    nil
  end
end

#exp_statement(var_env) ⇒ Object

Tests next literals sequence is ExpressionStatement or not.

See Also:



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/minjs/lex/statement.rb', line 164

def exp_statement(var_env)
  if (a = peek_lit(nil)).eql? ECMA262::PUNC_LCURLYBRAC
    return block(var_env)
  end
  if a.eql? ECMA262::ID_FUNCTION
    return func_declaration(var_env)
  end


  if a = exp(var_env, {})
    if semicolon(var_env)
      ECMA262::StExp.new(a)
    # There is a possibility of labelled statemet if
    # exp_statement call before labelled_statement
    else
      raise ParseError.new("no semicolon at end of expression statement", self)
    end
  else
    nil
  end
end

#if_statement(var_env) ⇒ Object

Tests next literals sequence is IfStatement or not.

See Also:



188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/minjs/lex/statement.rb', line 188

def if_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_IF)
  unless(eql_lit?(ECMA262::PUNC_LPARENTHESIS) and cond=exp(var_env, {}) and
         eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s = statement(var_env))
    raise ParseError.new("unexpected token", self)
  end
  if(eql_lit?(ECMA262::ID_ELSE) and e = statement(var_env))
    ECMA262::StIf.new(cond, s, e)
  else
    ECMA262::StIf.new(cond, s, nil)
  end
end

#iteration_statement(var_env) ⇒ Object

Tests next literals sequence is IterationStatement or not.

See Also:



203
204
205
# File 'lib/minjs/lex/statement.rb', line 203

def iteration_statement(var_env)
  for_statement(var_env) or while_statement(var_env) or do_while_statement(var_env)
end

#labelled_statement(var_env) ⇒ Object

Tests next literals sequence is LabelledStatement or not.

See Also:



402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/minjs/lex/statement.rb', line 402

def labelled_statement(var_env)
  eval_lit {
    if i=identifier(var_env) and s1=eql_lit?(ECMA262::PUNC_COLON)
      if s=statement(var_env)
        ECMA262::StLabelled.new(i, s)
      else
        raise ParseError.new("unexpected token", self)
      end
    else
      nil
    end
  }
end

#return_statement(var_env) ⇒ Object

Tests next literals sequence is ReturnStatement or not.

See Also:



337
338
339
340
341
342
343
344
345
346
347
# File 'lib/minjs/lex/statement.rb', line 337

def return_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_RETURN)

  if semicolon(var_env)
    ECMA262::StReturn.new
  elsif e=exp(var_env, {}) and semicolon(var_env)
    ECMA262::StReturn.new(e)
  else
    raise ParseError.new("unexpected token", self)
  end
end

#semicolon(var_env) ⇒ Object

Tests next literal is ‘;’ or ‘}’ or LT



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
# File 'lib/minjs/lex/statement.rb', line 8

def semicolon(var_env)
  a = peek_lit_nolt(nil)
  # ; ?
  if a == ECMA262::PUNC_SEMICOLON
    fwd_after_peek
    a
  # } ?
  elsif a == ECMA262::PUNC_RCURLYBRAC
    a
  # line feed?
  elsif a == ECMA262::LIT_LINE_TERMINATOR
    fwd_after_peek
    a
  # end of program
  elsif a.nil?
    fwd_after_peek
    ECMA262::LIT_LINE_TERMINATOR
  # line terminator?
  elsif a.lt?
    fwd_after_peek
    a
  else
    nil
  end
end

#statement(var_env) ⇒ Object

Tests next literals sequence is Statement or not.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/minjs/lex/statement.rb', line 35

def statement(var_env)
  (
    block(var_env) or		#12.1
    var_statement(var_env) or	#12.2
    if_statement(var_env) or	#12.5
    iteration_statement(var_env) or	#12.6
    continue_statement(var_env) or	#12.7
    break_statement(var_env) or	#12.8
    return_statement(var_env) or	#12.9
    with_statement(var_env) or	#12.10
    switch_statement(var_env) or	#12.11
    labelled_statement(var_env) or	#12.12
    throw_statement(var_env) or	#12.13
    try_statement(var_env) or	#12.14
    debugger_statement(var_env) or	#12.15
    func_declaration(var_env) or	#13 => func.rb
    exp_statement(var_env) or	#12.4
    empty_statement(var_env) 	#12.3
  )
end

#switch_statement(var_env) ⇒ Object

Tests next literals sequence is SwitchStatement or not.

See Also:



363
364
365
366
367
368
369
370
371
# File 'lib/minjs/lex/statement.rb', line 363

def switch_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_SWITCH)

  if eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(var_env, {}) and eql_lit?(ECMA262::PUNC_RPARENTHESIS) and  c = case_block(var_env)
    ECMA262::StSwitch.new(e, c)
  else
    raise ParseError.new("unexpected token", self)
  end
end

#throw_statement(var_env) ⇒ Object

Tests next literals sequence is ThrowStatement or not.

See Also:



418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/minjs/lex/statement.rb', line 418

def throw_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_THROW)

  if semicolon(var_env)
    raise ParseError.new("no line terminator here", self)
  elsif e=exp(var_env, {}) and semi = semicolon(var_env)
    ECMA262::StThrow.new(e)
  else
    if e
      raise ParseError.new("no semicolon at end of throw statement", self)
    else
      raise ParseError.new("unexpected token", self)
    end
  end
end

#try_statement(var_env) ⇒ Object

Tests next literals sequence is TryStatement or not.

See Also:



436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/minjs/lex/statement.rb', line 436

def try_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_TRY)
  #
  # The catch argument var_env must be executable lexical environment.
  # See compress_var
  #
  t = block(var_env)
  return nil unless t

  c = try_catch(var_env)
  f = try_finally(var_env)
  ECMA262::StTry.new(var_env, t, c, f)
end

#var_statement(var_env) ⇒ Object

Tests next literals sequence is VariableStatement or not.

See Also:



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/minjs/lex/statement.rb', line 84

def var_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_VAR)

  if vl = var_decl_list(var_env, {}) and semicolon(var_env)
    #10.5
    vl.each do |v|
      dn = v[0]
      var_env.record.create_mutable_binding(dn, nil)
      var_env.record.set_mutable_binding(dn, :undefined, nil)
    end
    ECMA262::StVar.new(var_env, vl)
  else
    raise Minjs::ParseError.new("unexpected token", lex)
  end
end

#with_statement(var_env) ⇒ Object

Tests next literals sequence is WithStatement or not.

See Also:



351
352
353
354
355
356
357
358
359
# File 'lib/minjs/lex/statement.rb', line 351

def with_statement(var_env)
  return nil unless eql_lit?(ECMA262::ID_WITH)

  if eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(var_env, {}) and eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(var_env)
    ECMA262::StWith.new(var_env, e, s)
  else
    raise ParseError.new("unexpected token", self)
  end
end