#include "WfEmitter.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
parsing
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
using
namespace
analyzer
;
using
namespace
runtime
;
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())
class
GenerateExpressionInstructionsVisitor
:
public
,
public
::
{
public
:
&
;
GenerateExpressionInstructionsVisitor
(
&
)
:context(
)
{
}
static
void
GenerateLoadSymbolInstructions
(
&
,
*
,
parsing
::
*
)
{
= -
1
;
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::CreateClosureContext(0));
INSTRUCTION(Ins::LoadFunction(functionIndex));
INSTRUCTION(Ins::CreateClosure());
}
else
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::LoadGlobalVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::LoadCapturedVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::LoadLocalVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::LoadLocalVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
)) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::LoadClosureContext());
INSTRUCTION(Ins::LoadFunction(functionIndex));
INSTRUCTION(Ins::CreateClosure());
}
else
{
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::GenerateLoadSymbolInstructions(WfCodegenContext&, WfLexicalSymbol*, ParsingTreeCustomBase*)#Internal error, cannot find any record of this symbol.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::GenerateLoadSymbolInstructions(WfCodegenContext&, WfLexicalSymbol*, ParsingTreeCustomBase*)#Internal error, cannot find any record of this symbol."
);}
while
(
0
);
}
}
static
(
&
,
*
,
*
)
{
auto
=
;
while
(
scope
)
{
if
(
scope
->
)
{
=
.
(
scope
);
if
(
scope
->
)
{
auto
=
.
->
scope
->
.
()];
=
capture
.
();
for
(
=
0
;
i
<
parentThisCount
;
i
++)
{
INSTRUCTION(Ins::LoadCapturedVar(captureCount + i));
.
(
,
::
(
captureCount
+
i
));
}
}
else
if
(
parentThisCount
>
0
)
{
CHECK_ERROR(parentThisCount == 1, L"GenerateExpressionInstructionsVisitor::PushCapturedThisValues(WfCodegenContext&, WfLexicalScope*, ParsingTreeCustomBase*)#Internal error, wrong parentThisCount value.");
do
{
if
(!(
parentThisCount
==
1
))
throw
(
L"GenerateExpressionInstructionsVisitor::PushCapturedThisValues(WfCodegenContext&, WfLexicalScope*, ParsingTreeCustomBase*)#Internal error, wrong parentThisCount value."
);}
while
(
0
);
INSTRUCTION(Ins::LoadCapturedVar(0));
}
return
parentThisCount
;
}
scope
=
scope
->
.
();
}
return
0
;
}
static
(
&
,
,
const
<
(
)>&
)
{
auto
=
<
>();
=
.
.
(
meta
);
meta
functionIndex
);
.
.
(
meta
,
functionIndex
);
.
.
(
functionIndex
,
);
return
functionIndex
;
}
void
(
*
,
const
&
)
{
auto
=
.
->
];
if
(
result
.
)
{
GenerateLoadSymbolInstructions
(
,
result
.
.
(),
);
}
else
if
(
result
.
)
{
if
(
result
.
->
())
{
INSTRUCTION(Ins::LoadValue({}));
}
else
{
(
,
result
.
->
());
}
INSTRUCTION(Ins::LoadMethodClosure(result.methodInfo));
}
else
if
(
result
.
)
{
if
(
auto
=
result
.
->
())
{
(
,
getter
->
());
INSTRUCTION(Ins::InvokeMethod(getter, 0));
}
else
{
(
,
result
.
->
());
INSTRUCTION(Ins::GetProperty(result.propertyInfo));
}
}
else
{
if
((
result
.
()->
()
::
) !=
::
)
{
auto
=
result
.
();
auto
=
td
->
();
=
enumType
->
(
);
if
(
index
!= -
1
)
{
auto
=
enumType
->
(
index
);
INSTRUCTION(Ins::LoadValue({ intValue, td }));
.
(
,
::
({
intValue
,
td
}));
return
;
}
}
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::VisitReferenceExpression(WfExpression*, const WString&)#Internal error, cannot find any record of this expression.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::VisitReferenceExpression(WfExpression*, const WString&)#Internal error, cannot find any record of this expression."
);}
while
(
0
);
}
}
void
(
*
,
*
)
{
auto
=
.
->
].
();
=
.
(
scope
);
=
0
;
<
>
;
<
>
;
while
(
scope
)
{
if
(
scope
->
)
{
if
(
scope
->
->
(
))
{
if
(
capture
)
{
INSTRUCTION(Ins::LoadCapturedVar(capture->symbols.Count() + count - offset - 1));
.
(
,
::
(
capture
.
() +
count
-
offset
-
1
));
}
else
{
INSTRUCTION(Ins::LoadCapturedVar(0));
}
return
;
}
else
{
offset
++;
}
if
(
lastConfig
)
{
if
(!
lastConfig
)
{
break
;
}
}
}
if
(
scope
->
)
{
lastConfig
scope
->
;
if
(!
capture
)
{
=
.
->
.
().
(
scope
->
.
());
if
(
index
!= -
1
)
{
capture
.
->
.
()
index
];
}
}
}
scope
=
scope
->
.
();
}
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::VisitThisExpression(WfExpression*, ITypeDescriptor*)#Internal error, cannot find any record of the this value.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::VisitThisExpression(WfExpression*, ITypeDescriptor*)#Internal error, cannot find any record of the this value."
);}
while
(
0
);
}
void
(
*
)
override
{
auto
=
.
->
].
();
while
(
scope
)
{
if
(
scope
->
)
{
if
(
scope
->
)
{
if
(
scope
->
)
{
auto
=
.
->
scope
->
.
()];
auto
=
.
(
scope
);
INSTRUCTION(Ins::LoadCapturedVar(capture->symbols.Count() + count - 1));
.
(
,
::
(
capture
.
() +
count
-
1
));
}
else
{
INSTRUCTION(Ins::LoadCapturedVar(0));
}
return
;
}
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::Visit(WfThisExpression*)#Internal error, this expression is illegal here.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::Visit(WfThisExpression*)#Internal error, this expression is illegal here."
);}
while
(
0
);
}
scope
=
scope
->
.
();
}
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::Visit(WfThisExpression*)#Internal error, this expression is illegal here.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::Visit(WfThisExpression*)#Internal error, this expression is illegal here."
);}
while
(
0
);
}
void
(
*
)
override
{
(
,
->
.
);
}
void
(
*
)
override
{
(
,
->
.
);
}
void
(
*
)
override
{
(
,
->
.
);
}
void
(
WfOrderedLambdaExpression
*
)
override
{
auto
=
.
->
].
();
;
lc
.
=
;
auto
=
(
,
lc
, [=](
)
{
return
L"<lambda:("
+
(
index
) +
L")> in "
+
.
;
});
auto
=
.
->
.
(
);
FOREACH(Ptr<WfLexicalSymbol>, symbol, capture->symbols)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
capture
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
symbol
);)
{
GenerateLoadSymbolInstructions
(
,
symbol
.
(),
);
}
=
(
,
scope
->
.
(),
);
INSTRUCTION(Ins::CreateClosureContext(capture->symbols.Count() + thisCount));
.
(
,
::
(
capture
.
() +
thisCount
));
INSTRUCTION(Ins::LoadFunction(functionIndex));
INSTRUCTION(Ins::CreateClosure());
}
void
(
*
)
override
{
auto
=
.
->
];
if
(
result
.
)
{
GenerateExpressionInstructions
(
,
->
);
if
(
result
.
->
())
{
INSTRUCTION(Ins::InvokeMethod(result.propertyInfo->GetGetter(), 0));
}
else
{
INSTRUCTION(Ins::GetProperty(result.propertyInfo));
}
}
else
{
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::LoadMethodClosure(result.methodInfo));
}
}
void
(
*
)
override
{
(
,
->
.
);
}
void
(
*
)
override
{
switch
(
->
)
{
case
::
:
INSTRUCTION(Ins::LoadValue({}));
break
;
case
::
:
INSTRUCTION(Ins::LoadValue({ true }));
break
;
case
::
:
INSTRUCTION(Ins::LoadValue({ false }));
break
;
}
}
#define INSTRUCTION_LOAD_VALUE(TYPE) if (td == description::GetTypeDescriptor<TYPE>()) { INSTRUCTION(Ins::LoadValue({ UnboxValue<TYPE>(output) })); return; }
void
(
*
)
override
{
auto
=
.
->
];
auto
=
result
.
();
;
td
->
()->
(
->
.
,
output
);
INSTRUCTION_LOAD_VALUE(float);
if
(
td
==
description
::
<
float
>()) {
.
(
,
::
({
<
float
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(double);
if
(
td
==
description
::
<
double
>()) {
.
(
,
::
({
<
double
>(
output
) }));
return
; };
CHECK_FAIL(L"Unrecognized value in WfFloatingExpression!");
do
{
throw
(
L"Unrecognized value in WfFloatingExpression!"
);}
while
(
0
);
}
void
(
*
)
override
{
auto
=
.
->
];
auto
=
result
.
();
;
td
->
()->
(
->
.
,
output
);
INSTRUCTION_LOAD_VALUE(vint8_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vint16_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vint32_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vint64_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vuint8_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vuint16_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vuint32_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(vuint64_t);
if
(
td
==
description
::
<
>()) {
.
(
,
::
({
<
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(float);
if
(
td
==
description
::
<
float
>()) {
.
(
,
::
({
<
float
>(
output
) }));
return
; };
INSTRUCTION_LOAD_VALUE(double);
if
(
td
==
description
::
<
double
>()) {
.
(
,
::
({
<
double
>(
output
) }));
return
; };
CHECK_FAIL(L"Unrecognized value in WfIntegerExpression!");
do
{
throw
(
L"Unrecognized value in WfIntegerExpression!"
);}
while
(
0
);
}
#undef INSTRUCTION_LOAD_VALUE
void
(
*
)
override
{
INSTRUCTION(Ins::LoadValue({ node->value.value }));
}
void
(
*
)
override
{
auto
=
GenerateExpressionInstructions
(
,
->
);
switch
(
->
)
{
case
::
:
INSTRUCTION(Ins::OpNot(GetInstructionTypeArgument(type)));
.
(
,
::
(
GetInstructionTypeArgument
(
type
)));
break
;
case
::
:
INSTRUCTION(Ins::OpPositive(GetInstructionTypeArgument(type)));
.
(
,
::
(
GetInstructionTypeArgument
(
type
)));
break
;
case
::
:
INSTRUCTION(Ins::OpNegative(GetInstructionTypeArgument(type)));
.
(
,
::
(
GetInstructionTypeArgument
(
type
)));
break
;
}
}
void
(
*
)
override
{
if
(
->
==
::
)
{
if
(
auto
=
->
.
<
>())
{
auto
=
.
->
binary
.
()];
auto
=
result
.
?
result
.
:
result
.
;
auto
=
containerType
()->
(
L"Set"
,
true
)->GetMethod(
0
);
GenerateExpressionInstructions
(
,
binary
);
INSTRUCTION(Ins::Duplicate(0));
GenerateExpressionInstructions
(
,
->
);
GenerateExpressionInstructions
(
,
binary
);
INSTRUCTION(Ins::InvokeMethod(methodInfo, 2));
}
else
if
(
auto
=
->
.
<
>())
{
auto
=
.
->
member
.
()];
if
(
auto
=
result
.
->
())
{
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::Duplicate(0));
GenerateExpressionInstructions
(
,
member
);
INSTRUCTION(Ins::InvokeMethod(methodInfo, 1));
}
else
{
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::Duplicate(0));
GenerateExpressionInstructions
(
,
member
);
INSTRUCTION(Ins::SetProperty(result.propertyInfo));
}
}
else
{
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::Duplicate(0));
auto
=
.
->
->
.
()];
= -
1
;
if
((
index
=
.
.
().
(
result
.
.
())) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::StoreGlobalVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
result
.
.
())) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::StoreLocalVar(variableIndex));
}
else
if
((
index
=
.
.
().
(
result
.
.
())) != -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::StoreCapturedVar(variableIndex));
}
else
if
(
result
.
)
{
if
(
auto
=
result
.
->
())
{
(
,
setter
->
());
INSTRUCTION(Ins::InvokeMethod(setter, 1));
}
else
{
(
,
result
.
->
());
INSTRUCTION(Ins::SetProperty(result.propertyInfo));
}
}
else
{
CHECK_FAIL(L"GenerateExpressionInstructionsVisitor::Visit(WfBinaryExpression*)#Internal error, cannot find any record of this assignable symbol.");
do
{
throw
(
L"GenerateExpressionInstructionsVisitor::Visit(WfBinaryExpression*)#Internal error, cannot find any record of this assignable symbol."
);}
while
(
0
);
}
}
}
else
if
(
->
==
::
)
{
auto
=
.
->
->
.
()];
auto
=
result
.
?
result
.
:
result
.
;
auto
=
containerType
()->
(
L"Get"
,
true
)->GetMethod(
0
);
GenerateExpressionInstructions
(
,
->
);
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::InvokeMethod(methodInfo, 1));
}
else
if
(
->
==
::
)
{
auto
=
.
->
].
;
if
(
type
() ==
description
::
<
>())
{
GenerateExpressionInstructions
(
,
->
,
type
);
GenerateExpressionInstructions
(
,
->
,
type
);
INSTRUCTION(Ins::OpConcat());
}
else
{
GenerateExpressionInstructions
(
,
->
,
type
);
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, description::GetTypeDescriptor<vuint64_t>()));
.
(
,
::
(
::
,
description
::
<
>()));
GenerateExpressionInstructions
(
,
->
,
type
);
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, description::GetTypeDescriptor<vuint64_t>()));
.
(
,
::
(
::
,
description
::
<
>()));
INSTRUCTION(Ins::OpAnd(WfInsType::U8));
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, type->GetTypeDescriptor()));
}
}
else
if
(
->
==
::
)
{
auto
=
.
->
].
;
GenerateExpressionInstructions
(
,
->
,
type
);
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, description::GetTypeDescriptor<vuint64_t>()));
.
(
,
::
(
::
,
description
::
<
>()));
GenerateExpressionInstructions
(
,
->
,
type
);
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, description::GetTypeDescriptor<vuint64_t>()));
.
(
,
::
(
::
,
description
::
<
>()));
INSTRUCTION(Ins::OpOr(WfInsType::U8));
INSTRUCTION(Ins::ConvertToType(Value::BoxedValue, type->GetTypeDescriptor()));
}
else
if
(
->
==
::
)
{
auto
=
.
->
];
vint trapInstruction = INSTRUCTION(Ins::InstallTry(-1));
GenerateExpressionInstructions
(
,
->
,
result
.
);
INSTRUCTION(Ins::UninstallTry(1));
vint finishInstruction = INSTRUCTION(Ins::Jump(-1));
FILL_LABEL_TO_CURRENT(trapInstruction);
.
trapInstruction
].
=
.
.
();
GenerateExpressionInstructions
(
,
->
,
result
.
);
FILL_LABEL_TO_CURRENT(finishInstruction);
.
finishInstruction
].
=
.
.
();
}
else
{
<
>
;
switch
(
->
)
{
case
::
:
case
::
:
case
::
:
case
::
:
case
::
:
case
::
:
case
::
:
case
::
:
{
auto
=
.
->
];
mergedType
result
.
;
}
break
;
default
:
{
auto
=
.
->
->
.
()];
auto
=
.
->
->
.
()];
auto
=
firstResult
.
?
firstResult
.
:
firstResult
.
;
auto
=
secondResult
.
?
secondResult
.
:
secondResult
.
;
if
(
->
==
::
||
->
==
::
)
{
if
(
firstType
() ==
::
||
firstType
() ==
::
)
{
GenerateExpressionInstructions
(
,
->
);
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::CompareReference());
if
(
->
==
::
)
{
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
}
return
;
}
}
mergedType
(
firstType
,
secondType
);
if
(
->
==
::
||
->
==
::
)
{
GenerateExpressionInstructions
(
,
->
);
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::CompareValue());
if
(
->
==
::
)
{
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
}
return
;
}
}
}
GenerateExpressionInstructions
(
,
->
,
mergedType
);
GenerateExpressionInstructions
(
,
->
,
mergedType
);
switch
(
->
)
{
case
::
:
INSTRUCTION(Ins::OpExp(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpAdd(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpSub(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpMul(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpDiv(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpMod(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpShl(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpShr(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpLT());
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpGT());
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpLE());
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpGE());
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpEQ());
break
;
case
::
:
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
INSTRUCTION(Ins::OpNE());
break
;
case
::
:
INSTRUCTION(Ins::OpXor(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpAnd(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
case
::
:
INSTRUCTION(Ins::OpOr(GetInstructionTypeArgument(mergedType)));
.
(
,
::
(
GetInstructionTypeArgument
(
mergedType
)));
break
;
default
:;
}
}
}
void
(
*
)
override
{
auto
=
.
->
].
();
<
>
(
->
.
());
auto
=
.
;
FOREACH_INDEXER(Ptr<WfLetVariable>, var, index, node->variables)
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__
.
(
var
);
index
++)
{
auto
=
scope
->
var
.
]
0
];
=
function
.
() +
function
.
(
L"<let>"
+
var
.
);
.
.
(
symbol
.
(),
variableIndex
);
variableIndices
index
] =
variableIndex
;
GenerateExpressionInstructions
(
,
var
);
INSTRUCTION(Ins::StoreLocalVar(variableIndex));
}
GenerateExpressionInstructions
(
,
->
);
FOREACH_INDEXER(Ptr<WfLetVariable>, var, index, node->variables)
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__
.
(
var
);
index
++)
{
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::StoreLocalVar(variableIndices[index]));
.
(
,
::
(
variableIndices
index
]));
}
}
void
(
*
)
override
{
auto
=
.
->
];
GenerateExpressionInstructions
(
,
->
);
vint fillTrueIndex = INSTRUCTION(Ins::JumpIf(-1));
GenerateExpressionInstructions
(
,
->
,
result
.
);
vint fillEndIndex = INSTRUCTION(Ins::Jump(-1));
FILL_LABEL_TO_CURRENT(fillTrueIndex);
GenerateExpressionInstructions
(
,
->
,
result
.
);
FILL_LABEL_TO_CURRENT(fillEndIndex);
}
void
(
*
)
override
{
auto
=
.
->
];
auto
=
result
.
()->
(
0
);
auto
=
GetInstructionTypeArgument
(
elementType
);
GenerateExpressionInstructions
(
,
->
,
elementType
);
if
(
->
==
::
)
{
INSTRUCTION(Ins::LoadValue({ (vint)1 }));
INSTRUCTION(Ins::OpAdd(type));
}
GenerateExpressionInstructions
(
,
->
,
elementType
);
if
(
->
==
::
)
{
INSTRUCTION(Ins::LoadValue({ (vint)1 }));
INSTRUCTION(Ins::OpSub(type));
}
INSTRUCTION(Ins::CreateRange(type));
}
void
(
*
)
override
{
if
(
auto
=
->
.
<
>())
{
auto
=
.
->
->
.
()];
auto
=
.
->
range
.
()];
auto
=
.
->
range
.
()];
auto
=
resultElement
.
?
resultElement
.
:
resultElement
.
;
auto
=
resultBegin
.
?
resultBegin
.
:
resultBegin
.
;
auto
=
resultEnd
.
?
resultEnd
.
:
resultEnd
.
;
auto
=
(
typeElement
,
typeBegin
);
auto
=
(
typeElement
,
typeEnd
);
auto
=
.
;
=
function
.
() +
function
.
(
L"<anonymous-range-test>"
);
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::StoreLocalVar(index));
INSTRUCTION(Ins::LoadLocalVar(index));
if
(!
(
typeElement
.
(),
typeLeft
.
()))
{
GenerateTypeCastInstructions
(
,
typeLeft
,
true
,
);
}
GenerateExpressionInstructions
(
,
range
,
typeLeft
);
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(typeLeft)));
.
(
,
::
(
GetInstructionTypeArgument
(
typeLeft
)));
if
(
range
==
::
)
{
INSTRUCTION(Ins::OpGT());
}
else
{
INSTRUCTION(Ins::OpGE());
}
INSTRUCTION(Ins::LoadLocalVar(index));
if
(!
(
typeElement
.
(),
typeRight
.
()))
{
GenerateTypeCastInstructions
(
,
typeRight
,
true
,
);
}
GenerateExpressionInstructions
(
,
range
,
typeRight
);
INSTRUCTION(Ins::CompareLiteral(GetInstructionTypeArgument(typeRight)));
.
(
,
::
(
GetInstructionTypeArgument
(
typeRight
)));
if
(
range
==
::
)
{
INSTRUCTION(Ins::OpLT());
}
else
{
INSTRUCTION(Ins::OpLE());
}
INSTRUCTION(Ins::OpAnd(WfInsType::Bool));
if
(
->
==
::
)
{
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
}
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::StoreLocalVar(index));
}
else
{
auto
=
.
->
->
.
()];
auto
=
result
.
?
result
.
:
result
.
;
GenerateExpressionInstructions
(
,
->
);
GenerateExpressionInstructions
(
,
->
);
auto
=
description
::
<
>();
if
(
result
.
()->
(
tdList
))
{
auto
=
tdList
->
(
L"Contains"
,
true
)->GetMethod(
0
);
INSTRUCTION(Ins::InvokeMethod(method, 1));
}
else
{
INSTRUCTION(Ins::TestElementInSet());
}
if
(
->
==
::
)
{
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
}
}
}
void
(
*
)
override
{
auto
=
.
->
];
if
(
result
.
()->
() ==
::
)
{
auto
=
result
.
();
INSTRUCTION(Ins::CreateStruct(Value::BoxedValue, td));
FOREACH(Ptr<WfConstructorArgument>, argument, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
auto
=
td
->
(
argument
.
<
>()
.
,
true
);
GenerateExpressionInstructions
(
,
argument
,
(
prop
->
()));
INSTRUCTION(Ins::UpdateProperty(prop));
}
}
else
if
(
result
.
() ==
description
::
<
>()
||
result
.
() ==
description
::
<
>()
||
result
.
() ==
description
::
<
>())
{
<
>
=
(
result
.
()->
(
0
));
FOREACH(Ptr<WfConstructorArgument>, argument, From(node->arguments).Reverse())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
(
->
).Reverse());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
GenerateExpressionInstructions
(
,
argument
,
keyType
);
}
INSTRUCTION(Ins::CreateArray(node->arguments.Count()));
}
else
if
(
result
.
() ==
description
::
<
>())
{
<
>
=
(
result
.
()->
(
0
));
FOREACH(Ptr<WfConstructorArgument>, argument, From(node->arguments).Reverse())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
(
->
).Reverse());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
GenerateExpressionInstructions
(
,
argument
,
keyType
);
}
INSTRUCTION(Ins::CreateObservableList(node->arguments.Count()));
}
else
{
<
>
=
(
result
.
()->
(
0
));
<
>
=
(
result
.
()->
(
1
));
FOREACH(Ptr<WfConstructorArgument>, argument, From(node->arguments).Reverse())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
(
->
).Reverse());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
GenerateExpressionInstructions
(
,
argument
,
keyType
);
GenerateExpressionInstructions
(
,
argument
,
valueType
);
}
INSTRUCTION(Ins::CreateMap(node->arguments.Count() * 2));
}
}
void
(
*
)
override
{
GenerateExpressionInstructions
(
,
->
);
}
void
(
*
)
override
{
if
(
->
==
::
)
{
auto
=
.
->
];
GenerateExpressionInstructions
(
,
->
,
result
.
);
}
else
{
auto
=
.
->
].
();
auto
=
(
scope
,
->
);
GenerateExpressionInstructions
(
,
->
);
GenerateTypeCastInstructions
(
,
type
,
false
,
);
}
}
void
(
*
)
override
{
switch
(
->
)
{
case
::
:
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::CompareReference());
break
;
case
::
:
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::CompareReference());
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
break
;
case
::
:
{
auto
=
.
->
].
();
auto
=
(
scope
,
->
);
GenerateExpressionInstructions
(
,
->
);
GenerateTypeTestingInstructions
(
,
type
,
);
}
break
;
case
::
:
{
auto
=
.
->
].
();
auto
=
(
scope
,
->
);
GenerateExpressionInstructions
(
,
->
);
GenerateTypeTestingInstructions
(
,
type
,
);
INSTRUCTION(Ins::OpNot(WfInsType::Bool));
}
break
;
}
}
void
(
*
)
override
{
auto
=
.
->
].
();
auto
=
(
scope
,
->
,
false
);
INSTRUCTION(Ins::LoadValue({ type->GetTypeDescriptor() }));
}
void
(
WfTypeOfExpressionExpression
*
)
override
{
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::GetType());
}
void
(
*
)
override
{
auto
=
.
->
->
.
()];
if
(
auto
=
->
.
<
>())
{
GenerateExpressionInstructions
(
,
member
);
}
else
{
(
,
result
.
->
());
}
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::AttachEvent(result.eventInfo));
}
void
(
*
)
override
{
auto
=
.
->
->
.
()];
if
(
auto
=
->
.
<
>())
{
GenerateExpressionInstructions
(
,
member
);
}
else
{
(
,
result
.
->
());
}
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::DetachEvent(result.eventInfo));
}
void
(
*
)
override
{
}
void
(
*
)
override
{
FOREACH(Ptr<WfExpression>, argument, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
GenerateExpressionInstructions
(
,
argument
);
}
auto
=
.
->
->
.
()];
if
(
result
.
)
{
if
(
result
.
->
())
{
INSTRUCTION(Ins::LoadValue({}));
}
else
if
(
auto
=
->
.
<
>())
{
GenerateExpressionInstructions
(
,
member
);
}
else
{
(
,
result
.
->
());
}
INSTRUCTION(Ins::InvokeMethod(result.methodInfo, node->arguments.Count()));
return
;
}
else
if
(
result
.
)
{
if
(
auto
=
->
.
<
>())
{
GenerateExpressionInstructions
(
,
member
);
}
else
{
(
,
result
.
->
());
}
INSTRUCTION(Ins::InvokeEvent(result.eventInfo, node->arguments.Count()));
return
;
}
else
if
(
result
.
)
{
if
(
result
.
.
<
>())
{
if
(
result
.
->
.
<
>())
{
=
.
result
.
.
()];
INSTRUCTION(Ins::InvokeWithContext(functionIndex, node->arguments.Count()));
.
(
,
::
(
functionIndex
,
->
.
()));
return
;
}
else
{
=
.
.
().
(
result
.
.
());
if
(
index
!= -
1
)
{
=
.
.
()
index
];
INSTRUCTION(Ins::Invoke(functionIndex, node->arguments.Count()));
.
(
,
::
(
functionIndex
,
->
.
()));
return
;
}
}
}
}
GenerateExpressionInstructions
(
,
->
);
INSTRUCTION(Ins::InvokeProxy(node->arguments.Count()));
}
static
void
(
&
,
*
,
,
const
<
(
)>&
)
{
auto
=
.
->
].
();
bool
=
scope
->
&&
scope
->
.
<
>();
auto
=
(
,
,
);
if
(
inNewInterfaceExpr
)
{
INSTRUCTION(Ins::LoadFunction(functionIndex));
}
else
{
auto
=
.
->
.
(
);
FOREACH(Ptr<WfLexicalSymbol>, symbol, capture->symbols)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
capture
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
symbol
);)
{
GenerateLoadSymbolInstructions
(
,
symbol
.
(),
);
}
=
(
,
scope
->
.
(),
);
INSTRUCTION(Ins::CreateClosureContext(capture->symbols.Count() + thisCount));
.
(
,
::
(
capture
.
() +
thisCount
));
INSTRUCTION(Ins::LoadFunction(functionIndex));
INSTRUCTION(Ins::CreateClosure());
}
}
void
(
*
)
override
{
;
lc
.
=
;
(
,
->
.
(),
lc
, [=](
)
{
return
L"<lambda:"
+
->
.
+
L"("
+
(
index
) +
L")> in "
+
.
;
});
}
class
NewInterfaceExpressionVisitor
:
public
empty_visitor
::
{
public
:
&
;
=
0
;
<
<
>>
;
<
<
>>
;
<
<
>>
;
*
=
nullptr
;
NewInterfaceExpressionVisitor
(
&
)
:context(
)
{
}
void
(
*
)
override
{
FOREACH(Ptr<WfDeclaration>, decl, node->expandedDeclarations)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
decl
);)
{
decl
(
this
);
}
}
void
(
*
)
override
{
CHECK_FAIL(L"NewInterfaceExpressionVisitor::Visit(WfVirtualCseDeclaration*)#Internal error, Temporary not supported.");
do
{
throw
(
L"NewInterfaceExpressionVisitor::Visit(WfVirtualCseDeclaration*)#Internal error, Temporary not supported."
);}
while
(
0
);
}
void
(
*
)
override
{
if
(!
)
{
=
;
}
if
(
->
==
::
)
{
.
(
);
}
else
{
.
(
);
}
}
void
(
*
)
override
{
++;
}
void
(
*
)
{
FOREACH(Ptr<WfDeclaration>, memberDecl, node->declarations)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
memberDecl
);)
{
memberDecl
(
this
);
}
if
(
!=
nullptr
&&
>
0
)
{
auto
=
.
->
.
(
);
(
,
(
capture
).Take(
));
}
}
};
void
(
*
)
override
{
auto
=
.
->
];
FOREACH(Ptr<WfExpression>, argument, node->arguments)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
->
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
argument
);)
{
GenerateExpressionInstructions
(
,
argument
);
}
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::InvokeMethod(result.constructorInfo, node->arguments.Count()));
}
void
(
*
)
override
{
auto
=
.
->
];
NewInterfaceExpressionVisitor
(
);
declVisitor
.
(
);
if
(
declVisitor
.
!=
nullptr
)
{
for
(
=
0
;
i
<
declVisitor
.
;
i
++)
{
auto
=
declVisitor
.
i
]
.
<
>();
GenerateExpressionInstructions
(
,
var
);
}
auto
=
.
->
.
(
declVisitor
.
);
for
(
=
declVisitor
.
;
i
<
capture
.
();
i
++)
{
GenerateLoadSymbolInstructions
(
,
capture
i
].
(),
);
}
auto
=
.
->
].
();
=
(
,
scope
,
);
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::CreateClosureContext(capture->symbols.Count() + thisCount + 1));
.
(
,
::
(
capture
.
() +
thisCount
+
1
));
FOREACH(Ptr<WfFunctionDeclaration>, func, declVisitor.closureFunctions)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
declVisitor
.
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
func
);)
{
;
lc
.
=
func
.
();
auto
=
(
,
lc
, [=](
)
{
return
L"<method:"
+
func
.
+
L"<"
+
result
.
()->
() +
L">("
+
(
index
) +
L")> in "
+
.
;
});
auto
=
.
->
func
.
()].
();
auto
=
.
->
(
scope
,
func
.
());
.
.
(
symbol
.
(),
functionIndex
);
}
FOREACH(Ptr<WfFunctionDeclaration>, func, declVisitor.overrideFunctions)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
<
>>&
= ::
vl
::
collections
::
(
declVisitor
.
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
<
>
;
__foreach_iterator__
.
(
func
);)
{
auto
=
.
->
func
.
()];
INSTRUCTION(Ins::LoadMethodInfo(methodInfo));
;
lc
.
=
func
.
();
(
,
func
.
(),
lc
, [=, &declVisitor](
)
{
return
L"<method:"
+
func
.
+
L"<"
+
result
.
()->
() +
L">("
+
(
index
+
declVisitor
.
.
()) +
L")> in "
+
.
;
});
}
}
else
{
INSTRUCTION(Ins::LoadValue({}));
INSTRUCTION(Ins::CreateClosureContext(1));
}
INSTRUCTION(Ins::CreateInterface(result.constructorInfo, declVisitor.overrideFunctions.Count() * 2));
.
(
,
::
(
result
.
,
declVisitor
.
.
() *
2
));
}
void
(
*
)
override
{
GenerateExpressionInstructions
(
,
->
);
}
void
(
*
)
override
{
GenerateExpressionInstructions
(
,
->
);
}
};
#undef FILL_LABEL_TO_CURRENT
#undef FILL_LABEL_TO_INS
#undef INSTRUCTION
<
reflection
::
description
::
>
GenerateExpressionInstructions
(
&
,
<
>
,
<
reflection
::
description
::
>
)
{
GenerateExpressionInstructionsVisitor
(
);
(&
visitor
);
auto
=
.
->
.
()];
auto
=
result
.
;
if
(
result
.
&& !
(
type
.
(),
result
.
.
()))
{
type
result
.
;
GenerateTypeCastInstructions
(
,
type
,
true
,
.
());
}
if
(
&& !
(
type
.
(),
.
()))
{
type
;
GenerateTypeCastInstructions
(
,
type
,
true
,
.
());
}
return
type
;
}
}
}
}