Skip to content

Commit 778fadc

Browse files
committed
[[ Compiler ]] Added support for 'use' clause
[[ Script ]] Added method to generate interface definition file from loaded module [[ Engine ]] Changed build rule for .mlc so that it outputs the interface file to <binaries>/modules
1 parent a09aaa9 commit 778fadc

File tree

16 files changed

+483
-54
lines changed

16 files changed

+483
-54
lines changed

engine/engine.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@
10171017
outputFiles = (
10181018
"$(DERIVED_FILE_DIR)/${INPUT_FILE_NAME}.c",
10191019
);
1020-
script = "\"${BUILT_PRODUCTS_DIR}/lc-compile\" -outputc \"${DERIVED_FILE_DIR}/${INPUT_FILE_NAME}.c\" \"${INPUT_FILE_PATH}\"";
1020+
script = "mkdir -p \"${BUILT_PRODUCTS_DIR}/modules\"\n\"${BUILT_PRODUCTS_DIR}/lc-compile\" -modulepath \"${BUILT_PRODUCTS_DIR}/modules\" -outputc \"${DERIVED_FILE_DIR}/${INPUT_FILE_NAME}.c\" \"${INPUT_FILE_PATH}\"";
10211021
};
10221022
/* End PBXBuildRule section */
10231023

libscript/include/script.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ bool MCScriptCopyHandlersOfModule(MCScriptModuleRef module, /* copy */ MCProperL
177177
// Query the signature of the given handler.
178178
bool MCScriptQueryHandlerOfModule(MCScriptModuleRef module, MCNameRef handler, /* get */ MCTypeInfoRef& r_signature);
179179

180+
// Emit an interface definition for the module.
181+
bool MCScriptWriteInterfaceOfModule(MCScriptModuleRef module, MCStreamRef stream);
182+
180183
// Retain a module.
181184
MCScriptModuleRef MCScriptRetainModule(MCScriptModuleRef module);
182185

libscript/libscript.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
outputFiles = (
7676
"$(DERIVED_FILE_DIR)/$(INPUT_FILE_NAME).c",
7777
);
78-
script = "\"${BUILT_PRODUCTS_DIR}/lc-compile\" -outputc \"${DERIVED_FILE_DIR}/${INPUT_FILE_NAME}.c\" \"${INPUT_FILE_PATH}\"";
78+
script = "mkdir -p \"${BUILT_PRODUCTS_DIR}/modules\"\n\"${BUILT_PRODUCTS_DIR}/lc-compile\" -modulepath \"${BUILT_PRODUCTS_DIR}/modules\" -outputc \"${DERIVED_FILE_DIR}/${INPUT_FILE_NAME}.c\" \"${INPUT_FILE_PATH}\"";
7979
};
8080
/* End PBXBuildRule section */
8181

libscript/src/script-builder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,8 @@ void MCScriptContinueHandlerTypeInModule(MCScriptModuleBuilderRef self, MCScript
499499
MCScriptHandlerType *t_type;
500500
t_type = static_cast<MCScriptHandlerType *>(self -> current_type);
501501

502-
if (!MCMemoryResizeArray(t_type -> parameter_count + 1, t_type -> parameters, t_type -> parameter_count))
502+
if (!MCMemoryResizeArray(t_type -> parameter_count + 1, t_type -> parameters, t_type -> parameter_count) ||
503+
!MCMemoryResizeArray(t_type -> parameter_name_count + 1, t_type -> parameter_names, t_type -> parameter_name_count))
503504
{
504505
self -> valid = false;
505506
return;
@@ -508,6 +509,7 @@ void MCScriptContinueHandlerTypeInModule(MCScriptModuleBuilderRef self, MCScript
508509
t_type -> parameters[t_type -> parameter_count - 1] . mode = p_mode;
509510
//t_type -> parameters[t_type -> parameter_count - 1] . name = MCValueRetain(p_name);
510511
t_type -> parameters[t_type -> parameter_count - 1] . type = p_type;
512+
t_type -> parameter_names[t_type -> parameter_name_count - 1] = MCValueRetain(p_name);
511513
}
512514

513515
void MCScriptEndHandlerTypeInModule(MCScriptModuleBuilderRef self, uindex_t& r_new_type)

libscript/src/script-module.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "script-private.h"
66

77
#include <stddef.h>
8+
#include <stdarg.h>
89

910
#ifdef _WIN32
1011
#include <windows.h>
@@ -34,6 +35,7 @@ MC_PICKLE_END_RECORD()
3435
MC_PICKLE_BEGIN_RECORD(MCScriptHandlerType)
3536
MC_PICKLE_ARRAY_OF_RECORD(MCScriptHandlerTypeParameter, parameters, parameter_count)
3637
MC_PICKLE_UINDEX(return_type)
38+
MC_PICKLE_ARRAY_OF_NAMEREF(parameter_names, parameter_name_count)
3739
MC_PICKLE_END_RECORD()
3840

3941
MC_PICKLE_BEGIN_RECORD(MCScriptRecordTypeField)
@@ -884,3 +886,166 @@ MCNameRef MCScriptGetNameOfGlobalVariableInModule(MCScriptModuleRef self, uindex
884886
}
885887

886888
////////////////////////////////////////////////////////////////////////////////
889+
890+
static int s_current_indent = 0;
891+
892+
static void __write(MCStreamRef stream, int p_indent, bool p_newline, const char *p_format, va_list p_args)
893+
{
894+
MCAutoStringRef t_formatted_string;
895+
MCStringFormatV(&t_formatted_string, p_format, p_args);
896+
MCAutoStringRef t_string;
897+
MCStringFormat(&t_string, "%.*s%@%s", p_indent * 2, " ", *t_formatted_string, p_newline ? "\n" : "");
898+
MCAutoStringRefAsUTF8String t_utf8_string;
899+
t_utf8_string . Lock(*t_string);
900+
MCStreamWrite(stream, *t_utf8_string, t_utf8_string . Size());
901+
}
902+
903+
static void __enterln(MCStreamRef stream, const char *format, ...)
904+
{
905+
va_list t_args;
906+
va_start(t_args, format);
907+
__write(stream, s_current_indent, true, format, t_args);
908+
va_end(t_args);
909+
s_current_indent += 1;
910+
}
911+
912+
static void __leaveln(MCStreamRef stream, const char *format, ...)
913+
{
914+
s_current_indent -= 1;
915+
va_list t_args;
916+
va_start(t_args, format);
917+
__write(stream, s_current_indent, true, format, t_args);
918+
va_end(t_args);
919+
}
920+
921+
static void __writeln(MCStreamRef stream, const char *format, ...)
922+
{
923+
va_list t_args;
924+
va_start(t_args, format);
925+
__write(stream, s_current_indent, true, format, t_args);
926+
va_end(t_args);
927+
}
928+
929+
static void def_to_name(MCScriptModuleRef self, uindex_t p_index, MCStringRef& r_string)
930+
{
931+
MCScriptDefinition *t_def;
932+
t_def = self -> definitions[p_index];
933+
if (t_def -> kind == kMCScriptDefinitionKindExternal)
934+
{
935+
MCScriptExternalDefinition *t_ext_def;
936+
t_ext_def = static_cast<MCScriptExternalDefinition *>(t_def);
937+
938+
MCStringFormat(r_string, "%@", /*self -> dependencies[self -> imported_definitions[t_ext_def -> index] . module] . name, */self -> imported_definitions[t_ext_def -> index] . name);
939+
}
940+
else
941+
MCStringFormat(r_string, "%@", self -> definition_names[p_index]);
942+
}
943+
944+
static void type_to_string(MCScriptModuleRef self, uindex_t p_type, MCStringRef& r_string)
945+
{
946+
MCScriptType *t_type;
947+
t_type = self -> types[p_type];
948+
switch(t_type -> kind)
949+
{
950+
case kMCScriptTypeKindDefined:
951+
def_to_name(self, static_cast<MCScriptDefinedType *>(t_type) -> index, r_string);
952+
break;
953+
case kMCScriptTypeKindOptional:
954+
{
955+
MCAutoStringRef t_target_name;
956+
type_to_string(self, static_cast<MCScriptOptionalType *>(t_type) -> type, &t_target_name);
957+
MCStringFormat(r_string, "optional %@", *t_target_name);
958+
}
959+
break;
960+
case kMCScriptTypeKindHandler:
961+
{
962+
MCAutoStringRef t_sig;
963+
MCScriptHandlerType *t_htype;
964+
t_htype = static_cast<MCScriptHandlerType *>(t_type);
965+
MCStringCreateMutable(0, &t_sig);
966+
MCStringAppendChar(*t_sig, '(');
967+
for(uindex_t i = 0; i < t_htype -> parameter_count; i++)
968+
{
969+
if (i != 0)
970+
MCStringAppendNativeChars(*t_sig, (const char_t *)", ", 2);
971+
static const char *s_mode_strings[] = {"in", "out", "inout"};
972+
MCAutoStringRef t_ptype;
973+
type_to_string(self, t_htype -> parameters[i] . type, &t_ptype);
974+
MCStringAppendFormat(*t_sig, "%s %@ as %@", s_mode_strings[t_htype -> parameters[i] . mode], t_htype -> parameter_names[i], *t_ptype);
975+
}
976+
MCAutoStringRef t_rtype;
977+
type_to_string(self, t_htype -> return_type, &t_rtype);
978+
MCStringAppendFormat(*t_sig, ") as %@", *t_rtype);
979+
MCStringCopy(*t_sig, r_string);
980+
}
981+
break;
982+
default:
983+
__MCScriptUnreachable__("inappropriate type found in definition");
984+
break;
985+
}
986+
}
987+
988+
bool MCScriptWriteInterfaceOfModule(MCScriptModuleRef self, MCStreamRef stream)
989+
{
990+
__enterln(stream, "import module %@", self -> name);
991+
for(uindex_t i = 0; i < self -> dependency_count; i++)
992+
{
993+
if (MCNameIsEqualTo(self -> dependencies[i] . name, MCNAME("__builtin__")))
994+
continue;
995+
996+
MCStringRef t_string;
997+
t_string = MCNameGetString(self -> dependencies[i] . name);
998+
999+
__writeln(stream, "use %@", self -> dependencies[i] . name);
1000+
}
1001+
for(uindex_t i = 0; i < self -> exported_definition_count; i++)
1002+
{
1003+
MCNameRef t_def_name;
1004+
MCScriptDefinition *t_def;
1005+
t_def_name = self -> exported_definitions[i] . name;
1006+
t_def = self -> definitions[self -> exported_definitions[i] . index];
1007+
switch(t_def -> kind)
1008+
{
1009+
case kMCScriptDefinitionKindType:
1010+
{
1011+
MCScriptType *t_type;
1012+
t_type = self -> types[static_cast<MCScriptTypeDefinition *>(t_def) -> type];
1013+
switch(t_type -> kind)
1014+
{
1015+
case kMCScriptTypeKindForeign:
1016+
__writeln(stream, "foreign type %@", t_def_name);
1017+
break;
1018+
}
1019+
}
1020+
break;
1021+
case kMCScriptDefinitionKindVariable:
1022+
{
1023+
MCAutoStringRef t_type_string;
1024+
type_to_string(self, static_cast<MCScriptVariableDefinition *>(t_def) -> type, &t_type_string);
1025+
__writeln(stream, "variable %@ as %@", t_def_name, *t_type_string);
1026+
}
1027+
break;
1028+
case kMCScriptDefinitionKindHandler:
1029+
{
1030+
MCAutoStringRef t_sig;
1031+
type_to_string(self, static_cast<MCScriptHandlerDefinition *>(t_def) -> type, &t_sig);
1032+
__writeln(stream, "handler %@%@", t_def_name, *t_sig);
1033+
}
1034+
break;
1035+
case kMCScriptDefinitionKindForeignHandler:
1036+
{
1037+
MCAutoStringRef t_sig;
1038+
type_to_string(self, static_cast<MCScriptForeignHandlerDefinition *>(t_def) -> type, &t_sig);
1039+
__writeln(stream, "foreign handler %@%@", t_def_name, *t_sig);
1040+
}
1041+
break;
1042+
default:
1043+
break;
1044+
}
1045+
}
1046+
__leaveln(stream, "end module");
1047+
1048+
return true;
1049+
}
1050+
1051+
////////////////////////////////////////////////////////////////////////////////

toolchain/lc-compile/src/bind.g

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@
1313
-- The purpose of the 'Bind' phase is to ensure every Id is assigned either a
1414
-- reference to the definingid() for its meaning, or the actual meaning if it is
1515
-- the defining id.
16-
'action' Bind(MODULE)
16+
'action' Bind(MODULE, MODULELIST)
1717

18-
'rule' Bind(Module:module(Position, Kind, Name, _, Imports, Definitions)):
18+
'rule' Bind(Module:module(Position, Kind, Name, _, Imports, Definitions), ImportedModules):
1919
DefineModuleId(Name)
2020

21+
-- Make sure all the imported modules are bound
22+
BindImports(Imports, ImportedModules)
23+
2124
-- Step 1: Ensure all id's referencing definitions point to the definition.
2225
-- and no duplicate definitions have been attempted.
2326
EnterScope
27+
-- Import all the used modules
28+
DeclareImports(Imports, ImportedModules)
2429
-- Declare the predefined ids
2530
DeclarePredefinedIds
2631
-- Assign the defining id to all top-level names.
@@ -34,6 +39,89 @@
3439

3540
--DumpBindings(Module)
3641

42+
'action' BindImports(IMPORT, MODULELIST)
43+
44+
'rule' BindImports(sequence(Left, Right), Imports):
45+
BindImports(Left, Imports)
46+
BindImports(Right, Imports)
47+
48+
'rule' BindImports(import(_, Id), Imports):
49+
Id'Name -> Name
50+
FindModuleInList(Name, Imports -> Module)
51+
Module'Name -> ModuleId
52+
(|
53+
QueryId(ModuleId -> module(Info))
54+
||
55+
DefineModuleId(ModuleId)
56+
Bind(Module, Imports)
57+
|)
58+
59+
'rule' BindImports(nil, _):
60+
-- do nothing
61+
--
62+
63+
'action' DeclareImports(IMPORT, MODULELIST)
64+
65+
'rule' DeclareImports(sequence(Left, Right), Imports):
66+
DeclareImports(Left, Imports)
67+
DeclareImports(Right, Imports)
68+
69+
'rule' DeclareImports(import(_, Id), Imports):
70+
Id'Name -> Name
71+
FindModuleInList(Name, Imports -> Module)
72+
Module'Definitions -> Definitions
73+
DeclareImportedDefinitions(Definitions)
74+
75+
'rule' DeclareImports(nil, _):
76+
-- do nothing
77+
78+
'action' DeclareImportedDefinitions(DEFINITION)
79+
80+
'rule' DeclareImportedDefinitions(sequence(Left, Right)):
81+
DeclareImportedDefinitions(Left)
82+
DeclareImportedDefinitions(Right)
83+
84+
'rule' DeclareImportedDefinitions(type(Position, _, Name, _)):
85+
DeclareId(Name)
86+
87+
'rule' DeclareImportedDefinitions(constant(Position, _, Name, _)):
88+
DeclareId(Name)
89+
90+
'rule' DeclareImportedDefinitions(variable(Position, _, Name, _)):
91+
DeclareId(Name)
92+
93+
'rule' DeclareImportedDefinitions(handler(Position, _, Name, _, _, _)):
94+
DeclareId(Name)
95+
96+
'rule' DeclareImportedDefinitions(foreignhandler(Position, _, Name, _, _)):
97+
DeclareId(Name)
98+
99+
'rule' DeclareImportedDefinitions(property(Position, _, Name, _, _)):
100+
DeclareId(Name)
101+
102+
'rule' DeclareImportedDefinitions(event(Position, _, Name, _)):
103+
DeclareId(Name)
104+
105+
'rule' DeclareImportedDefinitions(syntax(Position, _, Name, _, _, _)):
106+
DeclareId(Name)
107+
108+
'rule' DeclareImportedDefinitions(nil):
109+
-- do nothing
110+
111+
--
112+
113+
'action' FindModuleInList(NAME, MODULELIST -> MODULE)
114+
115+
'rule' FindModuleInList(Name, modulelist(Head, Rest) -> Head):
116+
Head'Name -> Id
117+
Id'Name -> ModName
118+
eq(Name, ModName)
119+
120+
'rule' FindModuleInList(Name, modulelist(_, Rest) -> Found):
121+
FindModuleInList(Name, Rest -> Found)
122+
123+
'action' QueryId(ID -> MEANING)
124+
37125
--------------------------------------------------------------------------------
38126

39127
-- The 'Declare' phase associates the meanings at the current scope with the

toolchain/lc-compile/src/check.g

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,7 @@
13691369
13701370
'rule' IsHighLevelType(any(_)):
13711371
'rule' IsHighLevelType(undefined(_)):
1372+
'rule' IsHighLevelType(foreign(_, _)):
13721373
'rule' IsHighLevelType(named(_, Id)):
13731374
QuerySymbolId(Id -> Info)
13741375
Info'Type -> Type

0 commit comments

Comments
 (0)