#include "WfEmitter.h"
namespace
{
namespace
{
namespace
{
using
namespace
parsing
;
using
namespace
reflection
::
description
;
using
namespace
analyzer
;
using
namespace
runtime
;
using
namespace
typeimpl
;
typedef
;
#define INSTRUCTION(X) context.AddInstruction(node, X)
#define FILL_LABEL_TO_INS(LABEL, INS) context.assembly->instructions[LABEL].indexParameter = INS
#define FILL_LABEL_TO_CURRENT(LABEL) FILL_LABEL_TO_INS(LABEL, context.assembly->instructions.Count())
void
GenerateTypeCastInstructions
(
&
,
<
reflection
::
description
::
>
,
bool
,
*
)
{
if
(
() !=
<
>())
{
= -
1
;
= -
1
;
if
(
() ==
::
)
{
INSTRUCTION(Ins::Duplicate(0));
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::CompareReference());
fillElseIndex = INSTRUCTION(Ins::JumpIf(-1));
fillElseIndex
=
.
(
,
::
(-
1
));
}
if
(
)
{
switch
(
())
{
case
::
:
INSTRUCTION(Ins::ConvertToType(Value::RawPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
INSTRUCTION(Ins::ConvertToType(Value::SharedPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
case
::
:
case
::
:
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, expectedType->GetTypeDescriptor()));
break
;
}
}
else
{
switch
(
())
{
case
::
:
INSTRUCTION(Ins::TryConvertToType(Value::RawPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
INSTRUCTION(Ins::TryConvertToType(Value::SharedPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
case
::
:
case
::
:
INSTRUCTION(Ins::TryConvertToType(Value::BoxedValue, expectedType->GetTypeDescriptor()));
break
;
}
}
if
(
fillElseIndex
!= -
1
)
{
fillEndIndex = INSTRUCTION(Ins::Jump(-1));
fillEndIndex
=
.
(
,
::
(-
1
));
FILL_LABEL_TO_CURRENT(fillElseIndex);
INSTRUCTION(Ins::LoadValue({}));
FILL_LABEL_TO_CURRENT(fillEndIndex);
}
}
}
void
GenerateTypeTestingInstructions
(
&
,
<
reflection
::
description
::
>
,
*
)
{
if
(
() !=
<
>())
{
switch
(
())
{
case
::
:
INSTRUCTION(Ins::TestType(Value::RawPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
INSTRUCTION(Ins::TestType(Value::SharedPtr, expectedType->GetTypeDescriptor()));
break
;
case
::
:
case
::
:
case
::
:
INSTRUCTION(Ins::TestType(Value::BoxedValue, expectedType->GetTypeDescriptor()));
break
;
}
}
else
{
INSTRUCTION(Ins::LoadValue({ true }));
}
}
runtime
::
GetInstructionTypeArgument
(
<
reflection
::
description
::
>
)
{
auto
=
();
if
(
td
==
<
bool
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
>())
return
::
;
if
(
td
==
<
float
>())
return
::
;
if
(
td
==
<
double
>())
return
::
;
if
(
td
==
<
>())
return
::
;
return
::
;
}
#define EXECUTE_CALLBACK(EXPR) if (callback) callback->EXPR
<
runtime
::
>
(
analyzer
::
*
,
*
)
{
EXECUTE_CALLBACK(OnGenerateMetadata());
auto
=
<
>();
assembly
new
;
assembly
new
;
(
assembly
,
);
FOREACH_INDEXER(Ptr<WfModule>, module, index, manager->GetModules())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
if
(
bool
=
true
)
for
(
=
0
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
module
);
index
++)
{
auto
=
->
()
index
];
auto
=
new
ParsingGeneratedLocationRecorder
(
context
.
nodePositionsBeforeCodegen
);
auto
=
new
ParsingGeneratedLocationRecorder
(
context
.
nodePositionsAfterCodegen
);
auto
=
new
ParsingOriginalLocationRecorder
(
recorderBefore
);
auto
=
new
ParsingMultiplePrintNodeRecorder
;
recorderMultiple
->
(
recorderOriginal
);
recorderMultiple
->
(
recorderAfter
);
stream
::
;
{
stream
::
(
memoryStream
);
(
streamWriter
,
recorderMultiple
,
index
);
(
module
,
L""
,
parsingWriter
);
}
memoryStream
.
(
0
);
auto
=
stream
::
(
memoryStream
).
();
assembly
.
(
codeBeforeCodegen
);
assembly
.
(
codeAfterCodegen
);
}
if
(
->
.
() >
0
)
{
assembly
new
;
FOREACH(Ptr<ITypeDescriptor>, td, manager->declarationTypes.Values())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
td
);)
{
if
(
auto
=
td
.
<
>())
{
assembly
.
(
tdClass
);
}
else
if
(
auto
=
td
.
<
>())
{
assembly
.
(
tdInterface
);
}
else
if
(
auto
=
td
.
<
>())
{
assembly
.
(
tdStruct
);
}
else
if
(
auto
=
td
.
<
>())
{
assembly
.
(
tdEnum
);
}
}
}
FOREACH(Ptr<WfModule>, module, manager->GetModules())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
module
);)
{
FOREACH(Ptr<WfDeclaration>, decl, module->declarations)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
module
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
decl
);)
{
GenerateGlobalDeclarationMetadata
(
context
,
decl
);
}
}
{
auto
=
<
>();
meta
=
L"<initialize>"
;
=
assembly
.
(
meta
);
assembly
.
(
meta
,
functionIndex
);
auto
=
<
>();
functionContext
meta
;
context
.
functionContext
;
meta
=
assembly
.
();
FOREACH(Ptr<WfModule>, module, manager->GetModules())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
module
);)
{
FOREACH(Ptr<WfDeclaration>, decl, module->declarations)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
module
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
decl
);)
{
GenerateInitializeInstructions
(
context
,
decl
);
}
}
parsing
::
*
=
nullptr
;
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::Return());
meta
=
assembly
.
() -
1
;
context
.
0
;
GenerateClosureInstructions
(
context
,
functionContext
);
}
FOREACH(Ptr<WfModule>, module, manager->GetModules())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
module
);)
{
EXECUTE_CALLBACK(OnGenerateCode(module));
FOREACH(Ptr<WfDeclaration>, decl, module->declarations)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
module
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
decl
);)
{
GenerateDeclarationInstructions
(
context
,
decl
);
}
}
EXECUTE_CALLBACK(OnGenerateDebugInfo());
assembly
();
return
assembly
;
}
#undef EXECUTE_CALLBACK
#undef FILL_LABEL_TO_CURRENT
#undef FILL_LABEL_TO_INS
#undef INSTRUCTION
<
runtime
::
>
(
<
parsing
::
tabling
::
>
,
analyzer
::
*
,
collections
::
<
>&
,
collections
::
<
<
parsing
::
>>&
)
{
->
(
true
,
true
);
FOREACH(WString, code, moduleCodes)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
;
__foreach_iterator__
.
(
code
);)
{
->
(
code
);
}
if
(
->
.
() >
0
)
{
(
,
->
);
return
0
;
}
->
(
true
);
if
(
->
.
() >
0
)
{
(
,
->
);
return
0
;
}
return
(
);
}
<
runtime
::
>
(
<
parsing
::
tabling
::
>
,
collections
::
<
>&
,
collections
::
<
<
parsing
::
>>&
)
{
(
);
return
(
, &
manager
,
,
);
}
}
}
}