-
Notifications
You must be signed in to change notification settings - Fork 7
/
component.go
111 lines (94 loc) 路 2.93 KB
/
component.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package desugarer
import (
"errors"
"maps"
"slices"
"github.com/nevalang/neva/internal/compiler"
src "github.com/nevalang/neva/internal/compiler/sourcecode"
)
var ErrConstSenderEntityKind = errors.New(
"Entity that is used as a const reference in component's network must be of kind constant",
)
type handleComponentResult struct {
desugaredComponent src.Component // desugared component to replace
virtualEntities map[string]src.Entity //nolint:lll // sometimes after desugaring component we need to insert some entities to the file
}
func (d Desugarer) handleComponent( //nolint:funlen
component src.Component,
scope src.Scope,
) (handleComponentResult, *compiler.Error) {
if len(component.Net) == 0 && len(component.Nodes) == 0 {
return handleComponentResult{desugaredComponent: component}, nil
}
virtualEntities := map[string]src.Entity{}
desugaredNodes, virtConnsForNodes, err := d.handleNodes(
component,
scope,
virtualEntities,
)
if err != nil {
return handleComponentResult{}, err
}
netToDesugar := append(virtConnsForNodes, component.Net...)
handleNetResult, err := d.handleNetwork(
netToDesugar,
desugaredNodes,
scope,
)
if err != nil {
return handleComponentResult{}, err
}
desugaredNetwork := slices.Clone(handleNetResult.desugaredConnections)
// add virtual constants created by network handler to virtual entities
for name, constant := range handleNetResult.virtualConstants {
virtualEntities[name] = src.Entity{
Kind: src.ConstEntity,
Const: constant,
}
}
// merge real nodes with virtual ones created by network handler
maps.Copy(desugaredNodes, handleNetResult.virtualNodes)
// create virtual destructor nodes and connections to handle unused outports
unusedOutports := d.findUnusedOutports(
component,
scope,
handleNetResult.usedNodePorts,
)
if unusedOutports.len() != 0 {
unusedOutportsResult := d.handleUnusedOutports(unusedOutports)
desugaredNetwork = append(desugaredNetwork, unusedOutportsResult.virtualConnections...)
desugaredNodes[unusedOutportsResult.voidNodeName] = unusedOutportsResult.voidNode
}
return handleComponentResult{
desugaredComponent: src.Component{
Directives: component.Directives,
Interface: component.Interface,
Nodes: desugaredNodes,
Net: desugaredNetwork,
Meta: component.Meta,
},
virtualEntities: virtualEntities,
}, nil
}
func (d Desugarer) handleNodes(
component src.Component,
scope src.Scope,
virtualEntities map[string]src.Entity,
) (map[string]src.Node, []src.Connection, *compiler.Error) {
desugaredNodes := make(map[string]src.Node, len(component.Nodes))
virtualConns := []src.Connection{}
for nodeName, node := range component.Nodes {
extraConns, err := d.handleNode(
scope,
node,
desugaredNodes,
nodeName,
virtualEntities,
)
if err != nil {
return nil, nil, err
}
virtualConns = append(virtualConns, extraConns...)
}
return desugaredNodes, virtualConns, nil
}