Skip to content

statics-comm.stx

pdmosses/metaborg-poosl/org.metaborg.lang.poosl/trans/statics-comm.stx

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
module statics-comm

imports
    signatures/Poosl-sig
    signatures/Common-sig
    statics-opt
    statics-names
    statics-expr-stat
    statics-typing

rules // === Ports and messages =======

     maps okPort(*, list(*))
     : scope * Port
    okPort(s, Port(name, _)) :- declarePort(s, name).

    okMessageSignatures maps okMessageSignature(*, list(*))
     : scope * MessageSignature
    okMessageSignature(, MessageReceiveSignature(, message, parameters, _)) :-
        typeOfPort(s, port),
        {} typesParameters == okOptMessageParameterList(s, parameters),
        declareReceiveMessage(s, port, message, TypeMessage(typesParameters)).
    okMessageSignature(, MessageSendSignature(, message, parameters, _)) :-
        typeOfPort(s, port),
        {} typesParameters == okOptMessageParameterList(s, parameters),
        declareSendMessage(s, port, message, TypeMessage(typesParameters)).

     : scope * OptMessageParameterList -> list(TypeDataClass)
    okOptMessageParameterList(s, MessageParameters(types)) = typeOfDataClasses(s, types).
    okOptMessageParameterList(s, NoMessageParameters()) = [].

rules // === Instances and channels =======

     maps okInstance(*, list(*))
     : scope * Instance
    okInstance(, Instance(annotationList, name, class, optParameterInstantiations)) :-
        {} T == typeOfProcessOrClusterClass(s, class),
        declareInstance(s, name, T),
        okInstanceParameters(s, externalScopeOfTypeProcessOrClusterClass(T), stripOptInstanceParameterList(optParameterInstantiations)).

    okInstanceParameters maps okInstanceParameter(*, *, list(*))
     : scope * scope * InstanceParameter
    okInstanceParameter(s, s_instance, InstanceParameter(name, )) :-
        {} T_var == typeOfVariable(s_instance, name),
        {} T_expr == okExpression(s, TypeDataClassRoot(), expr),
        try { compatibleType(T_var, T_expr) } | warning $[Incompatible type] @expr.

     maps okChannel(*, list(*))
     : scope * Channel
    okChannel(, Channel(annotationList, PortInstanceList())) :-
        {} count_ext_ports == countExternalPorts(portInstances),
        try { atMostOne(count_ext_ports) } | error $[There should be at most 1 external port],
        okPortInstances(s, portInstances),
        okChannelClosure(s, portInstances, count_ext_ports).

     : scope * list(PortInstance) * int
    okChannelClosure(s, pis, 0).
    okChannelClosure(s, pis, _).
        // TODO check unconnected messages
        // TODO check type compatibility of messages

    okPortInstances maps okPortInstance(*, list(*))
     : scope * PortInstance
    okPortInstance(s, InternalPort(instanceName, portName)) :-
        {} T_instance == typeOfInstance(s, instanceName),
        {} T_instance_scope ==  externalScopeOfTypeProcessOrClusterClass(T_instance),
        typeOfPort(T_instance_scope, portName).
    okPortInstance(s, ExternalPort(portName)) :-
        typeOfPort(s, portName).

rules

     : TypeProcessOrClusterClass -> scope
    externalScopeOfTypeProcessOrClusterClass(TypeClusterClass(s_external)) = s_external.
    externalScopeOfTypeProcessOrClusterClass(TypeProcessClass(s_external, s_internal)) = s_external.

rules

     : list(PortInstance) -> int
    countExternalPorts([]) = 0.
    countExternalPorts([ExternalPort(_)|Cs]) = len :- {t_len}
        t_len == countExternalPorts(Cs),
        len #= t_len + 1.
    countExternalPorts([_|Cs]) = countExternalPorts(Cs).

     : int
    atMostOne(0).
    atMostOne(1).