static T* get(lua_State* L, int index = -1) { type t = type_of(L, index); if (t == type::nil) return nullptr; return get_no_nil(L, index); }
//===================================================================== // type_of //===================================================================== sooty::parseme_ptr prism::resolve::type_of(sooty::const_parseme_ptr_ref N) { ATMA_ASSERT(N); switch (N->id) { // intrinsics case ID::int_type: case ID::real_type: case ID::bool_type: case ID::void_type: case ID::pointer_type: case ID::array_type: case ID::reference_type: case ID::any_type: return N; case ID::bitwidth: //return type_of( prism::synthesize::type_identifier(N, "bitwidth_type") ); return prism::resolve::bitwidth_type(N); case ID::identifier: { sooty::parseme_ptr D = prism::resolve::identifier_to_variable_definition(N); ATMA_ASSERT(D); if (!D) return type_of( prism::resolve::identifier_to_variable_definition(N) ); else return type_of(D); } case ID::type_identifier: { //return type_definition_of(N); sooty::parseme_ptr result = marshall::type_identifier::semantics::type_definition(N).parseme; ATMA_ASSERT(result); return result; } case ID::type_definition: return N; case ID::dereference: { sooty::parseme_ptr p = type_of(N->children[0]); ATMA_ASSERT(p->id == ID::pointer_type); return type_of(p->children[0]); } case ID::int_literal: return type_of( synthesize::int_type(N) ); case ID::real_literal: return type_of( synthesize::real_type(N) ); case ID::bool_literal: return synthesize::bool_type(N); case ID::string_literal: return synthesize::string_type(N); case ID::eq_operator: return type_of( N->children[0] ); case ID::add_operator: case ID::function: return type_of( marshall::function::return_type(N) ); case ID::function_call: return type_of( sooty::upwards_bredth_first_find_first_if(N, resolve::function_matches_function_call_pred(N)) ); case ID::member_function_call: return resolve::function_of_member_function_call( N ); case ID::variable_definition: return type_of( marshall::variable_definition::type(N) ); case ID::parameter: return type_of( marshall::parameter::type(N) ); case ID::un_reference: return type_of( N->children.front() ); case ID::address_of: { // we need to synthesize a new type sooty::parseme_ptr childtype = type_of(N->children[0]); sooty::parseme_ptr ptype = sooty::parseme::create( sooty::parseme_ptr(), ID::pointer_type, sooty::value_t(), sooty::lexical_position() ); ptype->children.push_back(childtype); return ptype; } case ID::new_: { // we need to synthesize a new type sooty::parseme_ptr childtype = type_of(N->children[0]); sooty::parseme_ptr ptype = sooty::parseme::create( sooty::parseme_ptr(), ID::pointer_type, sooty::value_t(), sooty::lexical_position() ); ptype->children.push_back(childtype); return ptype; } case ID::add: case ID::sub: case ID::mul: case ID::div: case ID::equ: return type_of( marshall::binary_expression::lhs(N) ); // expression of lhs (something), and rhs (the index) case ID::index_operator: { // currently we only support arrays and pointers. in the future we'll support // user-defined types having the member operator sooty::parseme_ptr lhs = marshall::binary_expression::lhs(N); sooty::parseme_ptr lhs_type = resolve::type_of(lhs); sooty::const_parseme_ptr_ref lhs_type_structure = resolve::type_structure_of(lhs_type); ATMA_ASSERT(lhs_type_structure->id == ID::array_type || lhs_type_structure->id == ID::pointer_type); if (lhs_type_structure->id == ID::pointer_type) { return resolve::type_of(marshall::pointer_type::pointee_type(lhs_type_structure)); } else if (lhs_type_structure->id == ID::array_type) { return resolve::type_of(marshall::array_type::type(lhs_type_structure)); } ATMA_HALT("bad!"); return sooty::parseme_ptr(); } case ID::member_operator: { sooty::const_parseme_ptr_ref lhs = marshall::binary_expression::lhs(N); sooty::const_parseme_ptr_ref rhs = marshall::binary_expression::rhs(N); // lhs! find its type-structure sooty::parseme_ptr lhs_type = resolve::type_of(lhs, resolve::remove_refs()); ATMA_ASSERT(lhs_type); // rhs! we need to find get the type-definition of the lhs and find the rhs's type in it ATMA_ASSERT( rhs->id == ID::identifier ); const std::string& rhs_identifier = marshall::binary_expression::rhs(N)->value.string; sooty::parseme_ptr member = resolve::member_of_type_definition( lhs_type, rhs_identifier ); if (member) return resolve::type_of(member); ATMA_HALT("bad!"); return sooty::parseme_ptr(); } case ID::intrinsic_int_add: case ID::intrinsic_int_sub: case ID::intrinsic_int_mul: case ID::intrinsic_int_div: return type_of(synthesize::int_type(N)); default: { ATMA_ASSERT(false && "not defined"); return sooty::parseme_ptr(); } } }