module Rucc::Parser::Initializer
Private Instance Methods
maybe_read_brace!()
click to toggle source
@return [Boolean]
# File lib/rucc/parser/initializer.rb, line 210 def maybe_read_brace! next_token?('{') end
maybe_skip_comma!()
click to toggle source
# File lib/rucc/parser/initializer.rb, line 214 def maybe_skip_comma! next_token?(',') end
read_array_initializer(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 57 def read_array_initializer(inits, ty, off, designated) read_array_initializer_sub(inits, ty, off, designated) sort_inits!(inits) end
read_array_initializer_sub(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param(return) [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 66 def read_array_initializer_sub(inits, ty, off, designated) has_brace = maybe_read_brace! flexible = ty.len <= 0 elemsize = ty.ptr.size i = 0 while flexible || i < ty.len tok = get if Token.is_keyword?(tok, '}') if !has_brace @lexer.unget_token(tok) end read_array_initializer_type(ty, elemsize, i) return end if (Token.is_keyword?(tok, '.') || Token.is_keyword?(tok, '[')) && !has_brace && !designated @lexer.unget_token(tok) return end if Token.is_keyword?(tok, '[') tok = peek idx = read_intexpr if (idx < 0) || (!flexible && ty.len <= idx) Util.errort!(tok, "array designator exceeds array bounds: #{idx}") end i = idx expect!(']') designated = true else @lexer.unget_token(tok) end read_initializer_elem(inits, ty.ptr, off + elemsize * i, designated) maybe_skip_comma! designated = false i += 1 end if has_brace skip_to_brace! end read_array_initializer_type(ty, elemsize, i) end
read_array_initializer_type(ty, elemsize, i)
click to toggle source
@param(return) [Type] ty @param [Integer] elemsize @param [Integer] i
# File lib/rucc/parser/initializer.rb, line 110 def read_array_initializer_type(ty, elemsize, i) if ty.len < 0 ty.len = i ty.size = elemsize * i end end
read_decl_init(ty)
click to toggle source
@param [Type] ty @return [Array]
# File lib/rucc/parser/initializer.rb, line 9 def read_decl_init(ty) r = [] if Token.is_keyword?(peek, '{') || Type.is_string(ty) read_initializer_list(r, ty, 0, false) else init = Node.conv(read_assignment_expr) if Type.is_arithtype(init.ty) && init.ty.kind != ty.kind init = Node.ast_conv(ty, init) end r.push Node.ast_init(init, ty, 0) end r end
read_initializer_elem(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param(return) [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 191 def read_initializer_elem(inits, ty, off, designated) next_token?('=') if (ty.kind == Kind::ARRAY) || (ty.kind == Kind::STRUCT) read_initializer_list(inits, ty, off, designated) elsif next_token?('{') read_initializer_elem(inits, ty, off, true) expect!('}') else expr = Node.conv(read_assignment_expr) Type.ensure_assignable!(ty, expr.ty) inits.push(Node.ast_init(expr, ty, off)) end end
read_initializer_list(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 27 def read_initializer_list(inits, ty, off, designated) tok = get if Type.is_string(ty) if tok.kind == T::STRING assign_string(inits, ty, tok.sval, off) return end if Token.is_keyword?(tok, '{') && (peek.kind == T::STRING) tok = get assign_string(inits, ty, tok.sval, off) expect!('}') return end end @lexer.unget_token(tok) if ty.kind == Kind::ARRAY read_array_initializer(inits, ty, off, designated) elsif ty.kind == Kind::STRUCT read_struct_initializer(inits, ty, off, designated) else arraytype = Type.make_array_type(ty, 1) read_array_initializer(inits, arraytype, off, designated) end end
read_struct_initializer(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 121 def read_struct_initializer(inits, ty, off, designated) read_struct_initializer_sub(inits, ty, off, designated) sort_inits!(inits) end
read_struct_initializer_sub(inits, ty, off, designated)
click to toggle source
@param(return) [Array] inits @param [Type] ty @param [Integer] off @param [Boolean] designated
# File lib/rucc/parser/initializer.rb, line 130 def read_struct_initializer_sub(inits, ty, off, designated) has_brace = maybe_read_brace! keys = ty.fields.keys i = 0 while true tok = get if Token.is_keyword?(tok, '}') if !has_brace @lexer.unget_token(tok) end return end if (Token.is_keyword?(tok, '.') || Token.is_keyword?(tok, '[')) && !has_brace && !designated @lexer.unget_token(tok) return end if Token.is_keyword?(tok, '.') tok = get if !tok || (tok.kind != T::IDENT) Util.errort!(tok, "malformed desginated initializer: #{tok}") end fieldname = tok.sval fieldtype = ty.fields[fieldname] if !fieldtype Util.errort!(tok, "field does not exist: #{tok}") end keys = ty.fields.keys i = 0 while i < keys.size s = keys[i] i += 1 if fieldname == s break end end designated = true else @lexer.unget_token(tok) if i == keys.size break end fieldname = keys[i] i += 1 fieldtype = ty.fields[fieldname] end read_initializer_elem(inits, fieldtype, off + fieldtype.offset, designated) maybe_skip_comma! designated = false if !ty.is_struct break end end if has_brace skip_to_brace! end end
skip_to_brace!()
click to toggle source
# File lib/rucc/parser/initializer.rb, line 218 def skip_to_brace! while true if next_token?('}') return end if next_token?('.') get expect!('=') end # tok = peek ignore = read_assignment_expr return if !ignore # TODO(south37) Impl warnt when necessary # warnt(tok, "excessive initializer: %s", node2s(ignore)); maybe_skip_comma!(); end end
sort_inits!(inits)
click to toggle source
# File lib/rucc/parser/initializer.rb, line 205 def sort_inits!(inits) inits.sort_by! { |init| init.initoff } end