Class: Rucc::Parser

Inherits:
Object
  • Object
show all
Includes:
Break, Builtin, Continue, Do, Ensure, Enum, Expr, For, Func, FuncCall, Goto, If, Initializer, Label, Return, StructAndUnion, Switch, While
Defined in:
lib/rucc/parser.rb,
lib/rucc/parser/do.rb,
lib/rucc/parser/if.rb,
lib/rucc/parser/for.rb,
lib/rucc/parser/enum.rb,
lib/rucc/parser/expr.rb,
lib/rucc/parser/func.rb,
lib/rucc/parser/goto.rb,
lib/rucc/parser/break.rb,
lib/rucc/parser/label.rb,
lib/rucc/parser/while.rb,
lib/rucc/parser/ensure.rb,
lib/rucc/parser/return.rb,
lib/rucc/parser/switch.rb,
lib/rucc/parser/builtin.rb,
lib/rucc/parser/continue.rb,
lib/rucc/parser/func_call.rb,
lib/rucc/parser/initializer.rb,
lib/rucc/parser/struct_and_union.rb

Defined Under Namespace

Modules: Break, Builtin, Continue, Do, Ensure, Enum, Expr, For, Func, FuncCall, Goto, If, Initializer, Label, Return, StructAndUnion, Switch, While

Instance Method Summary collapse

Methods included from Expr

#read_expr

Methods included from Enum

#read_enum_def

Constructor Details

#initialize(lexer, label_gen) ⇒ Parser

Returns a new instance of Parser.

Parameters:



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

def initialize(lexer, label_gen)
  @lexer = lexer

  @label_gen        = label_gen
  @tempname_gen     = TempnameGen.new
  @static_label_gen = StaticLabelGen.new

  # You can use the same name for global variable, local variable,
  # struct/union/enum tag, and goto label!
  @globalenv = RMap.new  # [RMap]
  @localenv  = nil       # [RMap, NilClass]
  @tags      = RMap.new  # [RMap, NilClass]
  @labels    = nil       # [RMap, NilClass]

  @toplevels = []   # [Array, NilClass]
  @localvars = nil  # [Array, NilClass]
  @gotos     = nil  # [Array, NilClass]
  @cases     = nil  # [Array, NilClass]

  @current_func_type = nil  # [Type, NilClass]

  @defaultcase = nil  # [String, NilClass]
  @lbreak = nil       # [String, NilClass]
  @lcontinue = nil    # [String, NilClass]

  define_builtin_functions!
end

Instance Method Details

#read_alignof_operandNode

Returns:



477
478
479
480
481
482
# File 'lib/rucc/parser/expr.rb', line 477

def read_alignof_operand
  expect!('(')
  ty = read_cast_type
  expect!(')')
  Node.ast_inttype(Type::ULONG, ty.align)
end

#read_sizeof_operandNode

Returns:



456
457
458
459
460
461
462
# File 'lib/rucc/parser/expr.rb', line 456

def read_sizeof_operand
  ty = read_sizeof_operand_sub
  # Sizeof on void or function type is GNU extension
  size = (ty.kind == Kind::VOID || ty.kind == Kind::FUNC) ? 1 : ty.size
  Util.assert!{ 0 <= size }
  Node.ast_inttype(Type::ULONG, size)
end

#read_sizeof_operand_subObject



465
466
467
468
469
470
471
472
473
474
# File 'lib/rucc/parser/expr.rb', line 465

def read_sizeof_operand_sub
  tok = get
  if Token.is_keyword?(tok, '(') && is_type?(peek)
    r = read_cast_type
    expect!(')')
    return r
  end
  @lexer.unget_token(tok)
  read_unary_expr.ty
end

#read_toplevelsObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rucc/parser.rb', line 83

def read_toplevels
  while true
    return @toplevels if (peek.kind == T::EOF)

    if is_funcdef?
      @toplevels.push(read_funcdef)
    elsif next_token?(K::STATIC_ASSERT)
      read_static_assert
    else
      read_decl(@toplevels, true)
    end
  end
  raise "Must not reach here"
end

#read_unary_incdec(op) ⇒ Node

Parameters:

Returns:



486
487
488
489
490
491
# File 'lib/rucc/parser/expr.rb', line 486

def read_unary_incdec(op)
  operand = read_unary_expr
  operand = Node.conv(operand)
  ensure_lvalue!(operand)
  Node.ast_uop(op, operand.ty, operand)
end