File Index Symbol Index

#include "WfEmitter.h"
namespace
vl
{
namespace
workflow
{
namespace
emitter
{
using
namespace
collections
;
using
namespace
parsing
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
using
namespace
analyzer
;
using
namespace
runtime
;
typedef
WfInstruction
Ins
;
#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())
/*********************************************************************** GenerateInstructions(Expression) ***********************************************************************/
class
GenerateExpressionInstructionsVisitor
:
public
Object
,
public
WfExpression
::
IVisitor
{
public
:
WfCodegenContext
&
context
;
GenerateExpressionInstructionsVisitor
(
WfCodegenContext
&
_context
) :context(
_context
) { }
static
void
GenerateLoadSymbolInstructions
(
WfCodegenContext
&
context
,
WfLexicalSymbol
*
symbol
,
parsing
::
ParsingTreeCustomBase
*
node
) {
vint
index
= -
1
;
if
((
index
=
context
.
globalFunctions
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
functionIndex
=
context
.
globalFunctions
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
globalVariables
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
variableIndex
=
context
.
globalVariables
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
functionContext
-
>
capturedVariables
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
variableIndex
=
context
.
functionContext
-
>
capturedVariables
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
functionContext
-
>
localVariables
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
variableIndex
=
context
.
functionContext
-
>
localVariables
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
functionContext
-
>
arguments
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
variableIndex
=
context
.
functionContext
-
>
arguments
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
closureFunctions
.
Keys
().
IndexOf
(
symbol
)) != -
1
) {
vint
functionIndex
=
context
.
closureFunctions
.
Values
()
[
index
]; }
else
{ } }
static
vint
PushCapturedThisValues
(
WfCodegenContext
&
context
,
WfLexicalScope
*
lambdaScopeParent
,
ParsingTreeCustomBase
*
node
) {
auto
scope
=
lambdaScopeParent
;
while
(
scope
) {
if
(
scope
->
functionConfig
) {
vint
parentThisCount
=
context
.
GetThisStackCount
(
scope
);
if
(
scope
->
functionConfig
-
>
lambda
) {
auto
capture
=
context
.
manager
->
lambdaCaptures
[
scope
->
ownerNode
.
Obj
()];
vint
captureCount
=
capture
-
>
symbols
.
Count
();
for
(
vint
i
=
0
;
i
<
parentThisCount
;
i
++) { } }
else
if
(
parentThisCount
>
0
) { }
return
parentThisCount
; }
scope
=
scope
->
parentScope
.
Obj
(); }
return
0
; }
static
vint
AddClosure
(
WfCodegenContext
&
context
,
WfCodegenLambdaContext
lc
,
const
Func
<
WString
(
vint
)>&
getName
) {
auto
meta
=
MakePtr
<
WfAssemblyFunction
>();
vint
functionIndex
=
context
.
assembly
-
>
functions
.
Add
(
meta
);
meta
-
>
name
=
getName
(
functionIndex
);
context
.
assembly
-
>
functionByName
.
Add
(
meta
-
>
name
,
functionIndex
);
context
.
functionContext
-
>
closuresToCodegen
.
Add
(
functionIndex
,
lc
);
return
functionIndex
; }
void
VisitReferenceExpression
(
WfExpression
*
node
,
const
WString
&
name
) {
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
if
(
result
.
symbol
) {
GenerateLoadSymbolInstructions
(
context
,
result
.
symbol
.
Obj
(),
node
); }
else
if
(
result
.
methodInfo
) {
if
(
result
.
methodInfo
->
IsStatic
()) { }
else
{
VisitThisExpression
(
node
,
result
.
methodInfo
->
GetOwnerTypeDescriptor
()); } }
else
if
(
result
.
propertyInfo
) {
if
(
auto
getter
=
result
.
propertyInfo
->
GetGetter
()) {
VisitThisExpression
(
node
,
getter
->
GetOwnerTypeDescriptor
()); }
else
{
VisitThisExpression
(
node
,
result
.
propertyInfo
->
GetOwnerTypeDescriptor
()); } }
else
{
if
((
result
.
type
-
>
GetTypeDescriptor
()->
GetTypeDescriptorFlags
()
&
TypeDescriptorFlags
::
EnumType
) !=
TypeDescriptorFlags
::
Undefined
) {
auto
td
=
result
.
type
-
>
GetTypeDescriptor
();
auto
enumType
=
td
->
GetEnumType
();
vint
index
=
enumType
->
IndexOfItem
(
name
);
if
(
index
!= -
1
) {
auto
intValue
=
enumType
->
GetItemValue
(
index
);
return
; } } } }
void
VisitThisExpression
(
WfExpression
*
node
,
ITypeDescriptor
*
td
) {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
vint
count
=
context
.
GetThisStackCount
(
scope
);
vint
offset
=
0
;
Ptr
<
WfLexicalCapture
>
capture
;
Ptr
<
WfLexicalFunctionConfig
>
lastConfig
;
while
(
scope
) {
if
(
scope
->
typeOfThisExpr
) {
if
(
scope
->
typeOfThisExpr
->
CanConvertTo
(
td
)) {
if
(
capture
) { }
else
{ }
return
; }
else
{
offset
++; }
if
(
lastConfig
) {
if
(!
lastConfig
-
>
parentThisAccessable
) {
break
; } } }
if
(
scope
->
functionConfig
) {
lastConfig
=
scope
->
functionConfig
;
if
(!
capture
) {
vint
index
=
context
.
manager
->
lambdaCaptures
.
Keys
().
IndexOf
(
scope
->
ownerNode
.
Obj
());
if
(
index
!= -
1
) {
capture
=
context
.
manager
->
lambdaCaptures
.
Values
()
[
index
]; } } }
scope
=
scope
->
parentScope
.
Obj
(); } }
void
Visit
(
WfThisExpression
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
while
(
scope
) {
if
(
scope
->
functionConfig
) {
if
(
scope
->
functionConfig
-
>
thisAccessable
) {
if
(
scope
->
functionConfig
-
>
lambda
) {
auto
capture
=
context
.
manager
->
lambdaCaptures
[
scope
->
ownerNode
.
Obj
()];
auto
count
=
context
.
GetThisStackCount
(
scope
); }
else
{ }
return
; } }
scope
=
scope
->
parentScope
.
Obj
(); } }
void
Visit
(
WfTopQualifiedExpression
*
node
)
override
{
VisitReferenceExpression
(
node
,
node
->
name
.
value
); }
void
Visit
(
WfReferenceExpression
*
node
)
override
{
VisitReferenceExpression
(
node
,
node
->
name
.
value
); }
void
Visit
(
WfOrderedNameExpression
*
node
)
override
{
VisitReferenceExpression
(
node
,
node
->
name
.
value
); }
void
Visit
(
WfOrderedLambdaExpression
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
WfCodegenLambdaContext
lc
;
lc
.
orderedLambdaExpression
=
node
;
auto
functionIndex
=
AddClosure
(
context
,
lc
, [=](
vint
index
) {
return
L"<lambda:("
+
itow
(
index
) +
L")> in "
+
context
.
functionContext
-
>
function
-
>
name
; });
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Get
(
node
); {
GenerateLoadSymbolInstructions
(
context
,
symbol
.
Obj
(),
node
); }
vint
thisCount
=
PushCapturedThisValues
(
context
,
scope
->
parentScope
.
Obj
(),
node
); }
void
Visit
(
WfMemberExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
if
(
result
.
propertyInfo
) {
GenerateExpressionInstructions
(
context
,
node
->
parent
);
if
(
result
.
propertyInfo
->
GetGetter
()) { }
else
{ } }
else
{
GenerateExpressionInstructions
(
context
,
node
->
parent
); } }
void
Visit
(
WfChildExpression
*
node
)
override
{
VisitReferenceExpression
(
node
,
node
->
name
.
value
); }
void
Visit
(
WfLiteralExpression
*
node
)
override
{
switch
(
node
->
value
) {
case
WfLiteralValue
::
Null
:
break
;
case
WfLiteralValue
::
True
:
break
;
case
WfLiteralValue
::
False
:
break
; } }
#define INSTRUCTION_LOAD_VALUE(TYPE) if (td == description::GetTypeDescriptor<TYPE>()) { INSTRUCTION(Ins::LoadValue({ UnboxValue<TYPE>(output) })); return; }
void
Visit
(
WfFloatingExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
auto
td
=
result
.
type
-
>
GetTypeDescriptor
();
Value
output
;
td
->
GetSerializableType
()->
Deserialize
(
node
->
value
.
value
,
output
); }
void
Visit
(
WfIntegerExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
auto
td
=
result
.
type
-
>
GetTypeDescriptor
();
Value
output
;
td
->
GetSerializableType
()->
Deserialize
(
node
->
value
.
value
,
output
); }
#undef INSTRUCTION_LOAD_VALUE
void
Visit
(
WfStringExpression
*
node
)
override
{ }
void
Visit
(
WfUnaryExpression
*
node
)
override
{
auto
type
=
GenerateExpressionInstructions
(
context
,
node
->
operand
);
switch
(
node
->
op
) {
case
WfUnaryOperator
::
Not
:
break
;
case
WfUnaryOperator
::
Positive
:
break
;
case
WfUnaryOperator
::
Negative
:
break
; } }
void
Visit
(
WfBinaryExpression
*
node
)
override
{
if
(
node
->
op
==
WfBinaryOperator
::
Assign
) {
if
(
auto
binary
=
node
->
first
.
Cast
<
WfBinaryExpression
>()) {
auto
result
=
context
.
manager
->
expressionResolvings
[
binary
-
>
first
.
Obj
()];
auto
containerType
=
result
.
expectedType
?
result
.
expectedType
:
result
.
type
;
auto
methodInfo
=
containerType
-
>
GetTypeDescriptor
()->
GetMethodGroupByName
(
L"Set"
,
true
)->GetMethod(
0
);
GenerateExpressionInstructions
(
context
,
binary
-
>
second
);
GenerateExpressionInstructions
(
context
,
node
->
second
);
GenerateExpressionInstructions
(
context
,
binary
-
>
first
); }
else
if
(
auto
member
=
node
->
first
.
Cast
<
WfMemberExpression
>()) {
auto
result
=
context
.
manager
->
expressionResolvings
[
member
.
Obj
()];
if
(
auto
methodInfo
=
result
.
propertyInfo
->
GetSetter
()) {
GenerateExpressionInstructions
(
context
,
node
->
second
);
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); }
else
{
GenerateExpressionInstructions
(
context
,
node
->
second
);
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); } }
else
{
GenerateExpressionInstructions
(
context
,
node
->
second
);
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
first
.
Obj
()];
vint
index
= -
1
;
if
((
index
=
context
.
globalVariables
.
Keys
().
IndexOf
(
result
.
symbol
.
Obj
())) != -
1
) {
vint
variableIndex
=
context
.
globalVariables
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
functionContext
-
>
localVariables
.
Keys
().
IndexOf
(
result
.
symbol
.
Obj
())) != -
1
) {
vint
variableIndex
=
context
.
functionContext
-
>
localVariables
.
Values
()
[
index
]; }
else
if
((
index
=
context
.
functionContext
-
>
capturedVariables
.
Keys
().
IndexOf
(
result
.
symbol
.
Obj
())) != -
1
) {
vint
variableIndex
=
context
.
functionContext
-
>
capturedVariables
.
Values
()
[
index
]; }
else
if
(
result
.
propertyInfo
) {
if
(
auto
setter
=
result
.
propertyInfo
->
GetSetter
()) {
VisitThisExpression
(
node
,
setter
->
GetOwnerTypeDescriptor
()); }
else
{
VisitThisExpression
(
node
,
result
.
propertyInfo
->
GetOwnerTypeDescriptor
()); } }
else
{ } } }
else
if
(
node
->
op
==
WfBinaryOperator
::
Index
) {
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
first
.
Obj
()];
auto
containerType
=
result
.
expectedType
?
result
.
expectedType
:
result
.
type
;
auto
methodInfo
=
containerType
-
>
GetTypeDescriptor
()->
GetMethodGroupByName
(
L"Get"
,
true
)->GetMethod(
0
);
GenerateExpressionInstructions
(
context
,
node
->
second
);
GenerateExpressionInstructions
(
context
,
node
->
first
); }
else
if
(
node
->
op
==
WfBinaryOperator
::
FlagAnd
) {
auto
type
=
context
.
manager
->
expressionResolvings
[
node
].
type
;
if
(
type
-
>
GetTypeDescriptor
() ==
description
::
GetTypeDescriptor
<
WString
>()) {
GenerateExpressionInstructions
(
context
,
node
->
first
,
type
);
GenerateExpressionInstructions
(
context
,
node
->
second
,
type
); }
else
{
GenerateExpressionInstructions
(
context
,
node
->
first
,
type
);
GenerateExpressionInstructions
(
context
,
node
->
second
,
type
); } }
else
if
(
node
->
op
==
WfBinaryOperator
::
FlagOr
) {
auto
type
=
context
.
manager
->
expressionResolvings
[
node
].
type
;
GenerateExpressionInstructions
(
context
,
node
->
first
,
type
);
GenerateExpressionInstructions
(
context
,
node
->
second
,
type
); }
else
if
(
node
->
op
==
WfBinaryOperator
::
FailedThen
) {
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
GenerateExpressionInstructions
(
context
,
node
->
first
,
result
.
type
);
GenerateExpressionInstructions
(
context
,
node
->
second
,
result
.
type
); }
else
{
Ptr
<
ITypeInfo
>
mergedType
;
switch
(
node
->
op
) {
case
WfBinaryOperator
::
Exp
:
case
WfBinaryOperator
::
Add
:
case
WfBinaryOperator
::
Sub
:
case
WfBinaryOperator
::
Mul
:
case
WfBinaryOperator
::
Div
:
case
WfBinaryOperator
::
Mod
:
case
WfBinaryOperator
::
Shl
:
case
WfBinaryOperator
::
Shr
: {
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
mergedType
=
result
.
type
; }
break
;
default
: {
auto
firstResult
=
context
.
manager
->
expressionResolvings
[
node
->
first
.
Obj
()];
auto
secondResult
=
context
.
manager
->
expressionResolvings
[
node
->
second
.
Obj
()];
auto
firstType
=
firstResult
.
expectedType
?
firstResult
.
expectedType
:
firstResult
.
type
;
auto
secondType
=
secondResult
.
expectedType
?
secondResult
.
expectedType
:
secondResult
.
type
;
if
(
node
->
op
==
WfBinaryOperator
::
EQ
||
node
->
op
==
WfBinaryOperator
::
NE
) {
if
(
firstType
-
>
GetDecorator
() ==
ITypeInfo
::
RawPtr
||
firstType
-
>
GetDecorator
() ==
ITypeInfo
::
SharedPtr
) {
GenerateExpressionInstructions
(
context
,
node
->
first
);
GenerateExpressionInstructions
(
context
,
node
->
second
);
if
(
node
->
op
==
WfBinaryOperator
::
NE
) { }
return
; } }
mergedType
=
GetMergedType
(
firstType
,
secondType
);
if
(
node
->
op
==
WfBinaryOperator
::
EQ
||
node
->
op
==
WfBinaryOperator
::
NE
) {
GenerateExpressionInstructions
(
context
,
node
->
first
);
GenerateExpressionInstructions
(
context
,
node
->
second
);
if
(
node
->
op
==
WfBinaryOperator
::
NE
) { }
return
; } } }
GenerateExpressionInstructions
(
context
,
node
->
first
,
mergedType
);
GenerateExpressionInstructions
(
context
,
node
->
second
,
mergedType
);
switch
(
node
->
op
) {
case
WfBinaryOperator
::
Exp
:
break
;
case
WfBinaryOperator
::
Add
:
break
;
case
WfBinaryOperator
::
Sub
:
break
;
case
WfBinaryOperator
::
Mul
:
break
;
case
WfBinaryOperator
::
Div
:
break
;
case
WfBinaryOperator
::
Mod
:
break
;
case
WfBinaryOperator
::
Shl
:
break
;
case
WfBinaryOperator
::
Shr
:
break
;
case
WfBinaryOperator
::
LT
:
break
;
case
WfBinaryOperator
::
GT
:
break
;
case
WfBinaryOperator
::
LE
:
break
;
case
WfBinaryOperator
::
GE
:
break
;
case
WfBinaryOperator
::
EQ
:
break
;
case
WfBinaryOperator
::
NE
:
break
;
case
WfBinaryOperator
::
Xor
:
break
;
case
WfBinaryOperator
::
And
:
break
;
case
WfBinaryOperator
::
Or
:
break
;
default
:; } } }
void
Visit
(
WfLetExpression
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
Array
<
vint
>
variableIndices
(
node
->
variables
.
Count
());
auto
function
=
context
.
functionContext
-
>
function
; {
auto
symbol
=
scope
->
symbols
[
var
-
>
name
.
value
]
[
0
];
vint
variableIndex
=
function
-
>
argumentNames
.
Count
() +
function
-
>
localVariableNames
.
Add
(
L"<let>"
+
var
-
>
name
.
value
);
context
.
functionContext
-
>
localVariables
.
Add
(
symbol
.
Obj
(),
variableIndex
);
variableIndices
[
index
] =
variableIndex
;
GenerateExpressionInstructions
(
context
,
var
-
>
value
); }
GenerateExpressionInstructions
(
context
,
node
->
expression
); { } }
void
Visit
(
WfIfExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
GenerateExpressionInstructions
(
context
,
node
->
condition
);
GenerateExpressionInstructions
(
context
,
node
->
falseBranch
,
result
.
type
);
GenerateExpressionInstructions
(
context
,
node
->
trueBranch
,
result
.
type
); }
void
Visit
(
WfRangeExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
auto
elementType
=
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
0
);
auto
type
=
GetInstructionTypeArgument
(
elementType
);
GenerateExpressionInstructions
(
context
,
node
->
begin
,
elementType
);
if
(
node
->
beginBoundary
==
WfRangeBoundary
::
Exclusive
) { }
GenerateExpressionInstructions
(
context
,
node
->
end
,
elementType
);
if
(
node
->
endBoundary
==
WfRangeBoundary
::
Exclusive
) { } }
void
Visit
(
WfSetTestingExpression
*
node
)
override
{
if
(
auto
range
=
node
->
collection
.
Cast
<
WfRangeExpression
>()) {
auto
resultElement
=
context
.
manager
->
expressionResolvings
[
node
->
element
.
Obj
()];
auto
resultBegin
=
context
.
manager
->
expressionResolvings
[
range
-
>
begin
.
Obj
()];
auto
resultEnd
=
context
.
manager
->
expressionResolvings
[
range
-
>
end
.
Obj
()];
auto
typeElement
=
resultElement
.
expectedType
?
resultElement
.
expectedType
:
resultElement
.
type
;
auto
typeBegin
=
resultBegin
.
expectedType
?
resultBegin
.
expectedType
:
resultBegin
.
type
;
auto
typeEnd
=
resultEnd
.
expectedType
?
resultEnd
.
expectedType
:
resultEnd
.
type
;
auto
typeLeft
=
GetMergedType
(
typeElement
,
typeBegin
);
auto
typeRight
=
GetMergedType
(
typeElement
,
typeEnd
);
auto
function
=
context
.
functionContext
-
>
function
;
vint
index
=
function
-
>
argumentNames
.
Count
() +
function
-
>
localVariableNames
.
Add
(
L"<anonymous-range-test>"
);
GenerateExpressionInstructions
(
context
,
node
->
element
);
if
(!
IsSameType
(
typeElement
.
Obj
(),
typeLeft
.
Obj
())) {
GenerateTypeCastInstructions
(
context
,
typeLeft
,
true
,
node
); }
GenerateExpressionInstructions
(
context
,
range
-
>
begin
,
typeLeft
);
if
(
range
-
>
beginBoundary
==
WfRangeBoundary
::
Exclusive
) { }
else
{ }
if
(!
IsSameType
(
typeElement
.
Obj
(),
typeRight
.
Obj
())) {
GenerateTypeCastInstructions
(
context
,
typeRight
,
true
,
node
); }
GenerateExpressionInstructions
(
context
,
range
-
>
end
,
typeRight
);
if
(
range
-
>
endBoundary
==
WfRangeBoundary
::
Exclusive
) { }
else
{ }
if
(
node
->
test
==
WfSetTesting
::
NotIn
) { } }
else
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
collection
.
Obj
()];
auto
type
=
result
.
expectedType
?
result
.
expectedType
:
result
.
type
;
GenerateExpressionInstructions
(
context
,
node
->
element
);
GenerateExpressionInstructions
(
context
,
node
->
collection
);
auto
tdList
=
description
::
GetTypeDescriptor
<
IValueReadonlyList
>();
if
(
result
.
type
-
>
GetTypeDescriptor
()->
CanConvertTo
(
tdList
)) {
auto
method
=
tdList
->
GetMethodGroupByName
(
L"Contains"
,
true
)->GetMethod(
0
); }
else
{ }
if
(
node
->
test
==
WfSetTesting
::
NotIn
) { } } }
void
Visit
(
WfConstructorExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
if
(
result
.
type
-
>
GetTypeDescriptor
()->
GetTypeDescriptorFlags
() ==
TypeDescriptorFlags
::
Struct
) {
auto
td
=
result
.
type
-
>
GetTypeDescriptor
(); {
auto
prop
=
td
->
GetPropertyByName
(
argument
-
>
key
.
Cast
<
WfReferenceExpression
>()
-
>
name
.
value
,
true
);
GenerateExpressionInstructions
(
context
,
argument
-
>
value
,
CopyTypeInfo
(
prop
->
GetReturn
())); } }
else
if
(
result
.
type
-
>
GetTypeDescriptor
() ==
description
::
GetTypeDescriptor
<
IValueEnumerable
>() ||
result
.
type
-
>
GetTypeDescriptor
() ==
description
::
GetTypeDescriptor
<
IValueReadonlyList
>() ||
result
.
type
-
>
GetTypeDescriptor
() ==
description
::
GetTypeDescriptor
<
IValueList
>()) {
Ptr
<
ITypeInfo
>
keyType
=
CopyTypeInfo
(
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
0
)); {
GenerateExpressionInstructions
(
context
,
argument
-
>
key
,
keyType
); } }
else
if
(
result
.
type
-
>
GetTypeDescriptor
() ==
description
::
GetTypeDescriptor
<
IValueObservableList
>()) {
Ptr
<
ITypeInfo
>
keyType
=
CopyTypeInfo
(
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
0
)); {
GenerateExpressionInstructions
(
context
,
argument
-
>
key
,
keyType
); } }
else
{
Ptr
<
ITypeInfo
>
keyType
=
CopyTypeInfo
(
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
0
));
Ptr
<
ITypeInfo
>
valueType
=
CopyTypeInfo
(
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
1
)); {
GenerateExpressionInstructions
(
context
,
argument
-
>
key
,
keyType
);
GenerateExpressionInstructions
(
context
,
argument
-
>
value
,
valueType
); } } }
void
Visit
(
WfInferExpression
*
node
)
override
{
GenerateExpressionInstructions
(
context
,
node
->
expression
); }
void
Visit
(
WfTypeCastingExpression
*
node
)
override
{
if
(
node
->
strategy
==
WfTypeCastingStrategy
::
Strong
) {
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
GenerateExpressionInstructions
(
context
,
node
->
expression
,
result
.
type
); }
else
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
type
=
CreateTypeInfoFromType
(
scope
,
node
->
type
);
GenerateExpressionInstructions
(
context
,
node
->
expression
);
GenerateTypeCastInstructions
(
context
,
type
,
false
,
node
); } }
void
Visit
(
WfTypeTestingExpression
*
node
)
override
{
switch
(
node
->
test
) {
case
WfTypeTesting
::
IsNull
:
GenerateExpressionInstructions
(
context
,
node
->
expression
);
break
;
case
WfTypeTesting
::
IsNotNull
:
GenerateExpressionInstructions
(
context
,
node
->
expression
);
break
;
case
WfTypeTesting
::
IsType
: {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
type
=
CreateTypeInfoFromType
(
scope
,
node
->
type
);
GenerateExpressionInstructions
(
context
,
node
->
expression
);
GenerateTypeTestingInstructions
(
context
,
type
,
node
); }
break
;
case
WfTypeTesting
::
IsNotType
: {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
type
=
CreateTypeInfoFromType
(
scope
,
node
->
type
);
GenerateExpressionInstructions
(
context
,
node
->
expression
);
GenerateTypeTestingInstructions
(
context
,
type
,
node
); }
break
; } }
void
Visit
(
WfTypeOfTypeExpression
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
type
=
CreateTypeInfoFromType
(
scope
,
node
->
type
,
false
); }
void
Visit
(
WfTypeOfExpressionExpression
*
node
)
override
{
GenerateExpressionInstructions
(
context
,
node
->
expression
); }
void
Visit
(
WfAttachEventExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
event
.
Obj
()];
if
(
auto
member
=
node
->
event
.
Cast
<
WfMemberExpression
>()) {
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); }
else
{
VisitThisExpression
(
node
,
result
.
eventInfo
->
GetOwnerTypeDescriptor
()); }
GenerateExpressionInstructions
(
context
,
node
->
function
); }
void
Visit
(
WfDetachEventExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
event
.
Obj
()];
if
(
auto
member
=
node
->
event
.
Cast
<
WfMemberExpression
>()) {
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); }
else
{
VisitThisExpression
(
node
,
result
.
eventInfo
->
GetOwnerTypeDescriptor
()); }
GenerateExpressionInstructions
(
context
,
node
->
handler
); }
void
Visit
(
WfObserveExpression
*
node
)
override
{ }
void
Visit
(
WfCallExpression
*
node
)
override
{ {
GenerateExpressionInstructions
(
context
,
argument
); }
auto
result
=
context
.
manager
->
expressionResolvings
[
node
->
function
.
Obj
()];
if
(
result
.
methodInfo
) {
if
(
result
.
methodInfo
->
IsStatic
()) { }
else
if
(
auto
member
=
node
->
function
.
Cast
<
WfMemberExpression
>()) {
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); }
else
{
VisitThisExpression
(
node
,
result
.
methodInfo
->
GetOwnerTypeDescriptor
()); }
return
; }
else
if
(
result
.
eventInfo
) {
if
(
auto
member
=
node
->
function
.
Cast
<
WfMemberExpression
>()) {
GenerateExpressionInstructions
(
context
,
member
-
>
parent
); }
else
{
VisitThisExpression
(
node
,
result
.
eventInfo
->
GetOwnerTypeDescriptor
()); }
return
; }
else
if
(
result
.
symbol
) {
if
(
result
.
symbol
-
>
creatorNode
.
Cast
<
WfFunctionDeclaration
>()) {
if
(
result
.
symbol
-
>
ownerScope
->
ownerNode
.
Cast
<
WfNewInterfaceExpression
>()) {
vint
functionIndex
=
context
.
closureFunctions
[
result
.
symbol
.
Obj
()];
return
; }
else
{
vint
index
=
context
.
globalFunctions
.
Keys
().
IndexOf
(
result
.
symbol
.
Obj
());
if
(
index
!= -
1
) {
vint
functionIndex
=
context
.
globalFunctions
.
Values
()
[
index
];
return
; } } } }
GenerateExpressionInstructions
(
context
,
node
->
function
); }
static
void
VisitFunction
(
WfCodegenContext
&
context
,
WfFunctionDeclaration
*
node
,
WfCodegenLambdaContext
lc
,
const
Func
<
WString
(
vint
)>&
getName
) {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
bool
inNewInterfaceExpr
=
scope
->
parentScope
&&
scope
->
parentScope
-
>
ownerNode
.
Cast
<
WfNewInterfaceExpression
>();
auto
functionIndex
=
AddClosure
(
context
,
lc
,
getName
);
if
(
inNewInterfaceExpr
) { }
else
{
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Get
(
node
); {
GenerateLoadSymbolInstructions
(
context
,
symbol
.
Obj
(),
node
); }
vint
thisCount
=
PushCapturedThisValues
(
context
,
scope
->
parentScope
.
Obj
(),
node
); } }
void
Visit
(
WfFunctionExpression
*
node
)
override
{
WfCodegenLambdaContext
lc
;
lc
.
functionExpression
=
node
;
VisitFunction
(
context
,
node
->
function
.
Obj
(),
lc
, [=](
vint
index
) {
return
L"<lambda:"
+
node
->
function
-
>
name
.
value
+
L"("
+
itow
(
index
) +
L")> in "
+
context
.
functionContext
-
>
function
-
>
name
; }); }
class
NewInterfaceExpressionVisitor
:
public
empty_visitor
::
DeclarationVisitor
{
public
:
WfCodegenContext
&
context
;
vint
variableCount
=
0
;
List
<
Ptr
<
WfLexicalSymbol
>>
variableSymbols
;
List
<
Ptr
<
WfFunctionDeclaration
>>
closureFunctions
;
List
<
Ptr
<
WfFunctionDeclaration
>>
overrideFunctions
;
WfFunctionDeclaration
*
firstFunction
=
nullptr
;
NewInterfaceExpressionVisitor
(
WfCodegenContext
&
_context
) :context(
_context
) { }
void
Dispatch
(
WfVirtualCfeDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Dispatch
(
WfVirtualCseDeclaration
*
node
)
override
{ }
void
Visit
(
WfFunctionDeclaration
*
node
)
override
{
if
(!
firstFunction
) {
firstFunction
=
node
; }
if
(
node
->
classMember
-
>
kind
==
WfClassMemberKind
::
Normal
) {
closureFunctions
.
Add
(
node
); }
else
{
overrideFunctions
.
Add
(
node
); } }
void
Visit
(
WfVariableDeclaration
*
node
)
override
{
variableCount
++; }
void
Execute
(
WfNewInterfaceExpression
*
node
) { {
memberDecl
-
>
Accept
(
this
); }
if
(
firstFunction
!=
nullptr
&&
variableCount
>
0
) {
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Get
(
firstFunction
);
CopyFrom
(
variableSymbols
,
From
(
capture
-
>
symbols
).Take(
variableCount
)); } } };
void
Visit
(
WfNewClassExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
]; {
GenerateExpressionInstructions
(
context
,
argument
); } }
void
Visit
(
WfNewInterfaceExpression
*
node
)
override
{
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
NewInterfaceExpressionVisitor
declVisitor
(
context
);
declVisitor
.
Execute
(
node
);
if
(
declVisitor
.
firstFunction
!=
nullptr
) {
for
(
vint
i
=
0
;
i
<
declVisitor
.
variableCount
;
i
++) {
auto
var
=
declVisitor
.
variableSymbols
[
i
]
-
>
creatorNode
.
Cast
<
WfVariableDeclaration
>();
GenerateExpressionInstructions
(
context
,
var
-
>
expression
); }
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Get
(
declVisitor
.
firstFunction
);
for
(
vint
i
=
declVisitor
.
variableCount
;
i
<
capture
-
>
symbols
.
Count
();
i
++) {
GenerateLoadSymbolInstructions
(
context
,
capture
-
>
symbols
[
i
].
Obj
(),
node
); }
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
vint
thisCount
=
PushCapturedThisValues
(
context
,
scope
,
node
); {
WfCodegenLambdaContext
lc
;
lc
.
functionDeclaration
=
func
.
Obj
();
auto
functionIndex
=
AddClosure
(
context
,
lc
, [=](
vint
index
) {
return
L"<method:"
+
func
-
>
name
.
value
+
L"<"
+
result
.
type
-
>
GetTypeDescriptor
()->
GetTypeName
() +
L">("
+
itow
(
index
) +
L")> in "
+
context
.
functionContext
-
>
function
-
>
name
; });
auto
scope
=
context
.
manager
->
nodeScopes
[
func
.
Obj
()].
Obj
();
auto
symbol
=
context
.
manager
->
GetDeclarationSymbol
(
scope
,
func
.
Obj
());
context
.
closureFunctions
.
Add
(
symbol
.
Obj
(),
functionIndex
); } {
auto
methodInfo
=
context
.
manager
->
interfaceMethodImpls
[
func
.
Obj
()];
WfCodegenLambdaContext
lc
;
lc
.
functionDeclaration
=
func
.
Obj
();
VisitFunction
(
context
,
func
.
Obj
(),
lc
, [=, &declVisitor](
vint
index
) {
return
L"<method:"
+
func
-
>
name
.
value
+
L"<"
+
result
.
type
-
>
GetTypeDescriptor
()->
GetTypeName
() +
L">("
+
itow
(
index
+
declVisitor
.
closureFunctions
.
Count
()) +
L")> in "
+
context
.
functionContext
-
>
function
-
>
name
; }); } }
else
{ } }
void
Visit
(
WfVirtualCfeExpression
*
node
)
override
{
GenerateExpressionInstructions
(
context
,
node
->
expandedExpression
); }
void
Visit
(
WfVirtualCseExpression
*
node
)
override
{
GenerateExpressionInstructions
(
context
,
node
->
expandedExpression
); } };
#undef FILL_LABEL_TO_CURRENT
#undef FILL_LABEL_TO_INS
#undef INSTRUCTION
Ptr
<
reflection
::
description
::
ITypeInfo
>
GenerateExpressionInstructions
(
WfCodegenContext
&
context
,
Ptr
<
WfExpression
>
expression
,
Ptr
<
reflection
::
description
::
ITypeInfo
>
expectedType
) {
GenerateExpressionInstructionsVisitor
visitor
(
context
);
expression
-
>
Accept
(&
visitor
);
auto
result
=
context
.
manager
->
expressionResolvings
[
expression
.
Obj
()];
auto
type
=
result
.
type
;
if
(
result
.
expectedType
&& !
IsSameType
(
type
.
Obj
(),
result
.
expectedType
.
Obj
())) {
type
=
result
.
expectedType
;
GenerateTypeCastInstructions
(
context
,
type
,
true
,
expression
.
Obj
()); }
if
(
expectedType
&& !
IsSameType
(
type
.
Obj
(),
expectedType
.
Obj
())) {
type
=
expectedType
;
GenerateTypeCastInstructions
(
context
,
type
,
true
,
expression
.
Obj
()); }
return
type
; } } } }