Skip to content

Commit 0153a39

Browse files
committed
[[ Bug 20325 ]] Add notion of foreign type constructor
This patch adds the notion of a 'foreign type constructor'. This expands the foreign type clause in lcb to allow a binding string of the form "<name>:<args>". Here, name is resolved as a C function with prototype bool (*)(MCStringRef, MCTypeInfoRef&). Where the first argument is passed the args part of the binding string. The function should create a new typeinfo based on the arguments it is given.
1 parent fe48f0d commit 0153a39

1 file changed

Lines changed: 64 additions & 32 deletions

File tree

libscript/src/script-module.cpp

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -750,43 +750,75 @@ bool MCScriptEnsureModuleIsUsable(MCScriptModuleRef self)
750750
MCScriptForeignType *t_type;
751751
t_type = static_cast<MCScriptForeignType *>(self -> types[i]);
752752

753-
bool t_is_builtin = false;
754-
void *t_symbol = nullptr;
755-
integer_t t_ordinal = 0;
756-
if (self->builtins != nullptr &&
757-
MCTypeConvertStringToLongInteger(t_type->binding, t_ordinal))
753+
uindex_t t_offset = 0;
754+
if (!MCStringFirstIndexOfChar(t_type->binding, ':', 0, kMCStringOptionCompareExact, t_offset))
758755
{
759-
t_symbol = self->builtins[t_ordinal];
760-
t_is_builtin = true;
761-
}
762-
else
763-
{
764-
t_symbol = MCSLibraryLookupSymbol(MCScriptGetLibrary(),
765-
t_type->binding);
766-
t_is_builtin = false;
767-
}
768-
769-
if (t_symbol == nullptr)
770-
{
771-
MCErrorThrowGenericWithMessage(MCSTR("%{name} not usable - unable to resolve foreign type '%{type}'"),
772-
"name", self -> name,
773-
"type", t_type -> binding,
774-
nil);
775-
goto error_cleanup;
776-
}
756+
bool t_is_builtin = false;
757+
void *t_symbol = nullptr;
758+
integer_t t_ordinal = 0;
759+
if (self->builtins != nullptr &&
760+
MCTypeConvertStringToLongInteger(t_type->binding, t_ordinal))
761+
{
762+
t_symbol = self->builtins[t_ordinal];
763+
t_is_builtin = true;
764+
}
765+
else
766+
{
767+
t_symbol = MCSLibraryLookupSymbol(MCScriptGetLibrary(),
768+
t_type->binding);
769+
t_is_builtin = false;
770+
}
771+
772+
if (t_symbol == nullptr)
773+
{
774+
MCErrorThrowGenericWithMessage(MCSTR("%{name} not usable - unable to resolve foreign type '%{type}'"),
775+
"name", self -> name,
776+
"type", t_type -> binding,
777+
nil);
778+
goto error_cleanup;
779+
}
777780

778-
/* The symbol is a function that returns a type info reference. */
779-
if (t_is_builtin)
780-
{
781-
MCTypeInfoRef t_typeinfo_bare;
782-
void (*t_type_func_builtin)(void*rv, void**av) = (void(*)(void*, void**))t_symbol;
783-
t_type_func_builtin(&t_typeinfo_bare, nullptr);
784-
t_typeinfo = t_typeinfo_bare;
781+
/* The symbol is a function that returns a type info reference. */
782+
if (t_is_builtin)
783+
{
784+
MCTypeInfoRef t_typeinfo_bare;
785+
void (*t_type_func_builtin)(void*rv, void**av) = (void(*)(void*, void**))t_symbol;
786+
t_type_func_builtin(&t_typeinfo_bare, nullptr);
787+
t_typeinfo = t_typeinfo_bare;
788+
}
789+
else
790+
{
791+
MCTypeInfoRef (*t_type_func)(void) = (MCTypeInfoRef (*)(void)) t_symbol;
792+
t_typeinfo = t_type_func();
793+
}
785794
}
786795
else
787796
{
788-
MCTypeInfoRef (*t_type_func)(void) = (MCTypeInfoRef (*)(void)) t_symbol;
789-
t_typeinfo = t_type_func();
797+
MCAutoStringRef t_type_func, t_args;
798+
if (!MCStringDivideAtChar(t_type->binding, ':', kMCStringOptionCompareExact, &t_type_func, &t_args))
799+
{
800+
goto error_cleanup;
801+
}
802+
803+
void *t_symbol =
804+
MCSLibraryLookupSymbol(MCScriptGetLibrary(),
805+
*t_type_func);
806+
if (t_symbol == nullptr)
807+
{
808+
MCErrorThrowGenericWithMessage(MCSTR("%{name} not usable - unable to resolve foreign type constructor '%{type}'"),
809+
"name", self -> name,
810+
"type", *t_type_func,
811+
nil);
812+
goto error_cleanup;
813+
}
814+
815+
bool (*t_type_constructor)(MCStringRef p_binding, MCTypeInfoRef& r_typeinfo) =
816+
(bool(*)(MCStringRef, MCTypeInfoRef&))t_symbol;
817+
818+
if (!t_type_constructor(*t_args, &t_typeinfo))
819+
{
820+
goto error_cleanup;
821+
}
790822
}
791823
}
792824
break;

0 commit comments

Comments
 (0)