forked from eth-sri/bayonet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscope_.d
142 lines (129 loc) · 3.94 KB
/
scope_.d
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import std.format;
import std.typecons: Tuple, tuple;
import std.conv: text;
import lexer, expression, declaration, error;
abstract class Scope{
abstract @property ErrorHandler handler();
abstract @property PacketFieldScope packetFieldScope();
bool insert(Declaration decl)in{assert(!decl.scope_);}body{
auto d=symtabLookup(decl.name);
if(d){
redefinitionError(decl, d);
decl.sstate=SemState.error;
return false;
}
symtab[decl.name.ptr]=decl;
decl.scope_=this;
return true;
}
void redefinitionError(Declaration decl, Declaration prev) in{
assert(decl);
assert(decl.name.ptr is prev.name.ptr);
}body{
error(format("redefinition of '%s'",decl.name), decl.name.loc);
note("previous definition was here",prev.name.loc);
}
protected final Declaration symtabLookup(Identifier ident){
return symtab.get(ident.ptr, null);
}
Declaration lookup(Identifier ident){
return lookupHere(ident);
}
final Declaration lookupHere(Identifier ident){
auto r = symtabLookup(ident);
return r;
}
bool isNestedIn(Scope rhs){ return rhs is this; }
void error(lazy string err, Location loc){handler.error(err,loc);}
void note(lazy string err, Location loc){handler.note(err,loc);}
abstract FunctionDef getFunction();
private:
Declaration[const(char)*] symtab;
}
class TopScope: Scope{
private ErrorHandler handler_;
override @property ErrorHandler handler(){ return handler_; }
PacketFieldScope pkt;
override @property PacketFieldScope packetFieldScope(){
return pkt;
}
this(ErrorHandler handler){
this.handler_=handler;
this.pkt=new PacketFieldScope(this);
}
private TopologyDecl topology;
private NodeDecl[const(char)*] nodes;
private Tuple!(NodeDecl,int,Location)[Tuple!(NodeDecl,int)] graph;
NodeDecl lookupNode(Identifier name){
if(name.name.ptr in nodes) return nodes[name.name.ptr];
error("undefined node '"~name.name~"'",name.loc);
return null;
}
final bool setTopology(TopologyDecl topology)in{assert(!this.topology);}body{
this.topology=topology;
bool err=false;
foreach(n;topology.nodes){
if(n.name.name.ptr in nodes){
error(text("redeclaration of node ",n.name),n.loc);
note("previous declaration was here",nodes[n.name.name.ptr].loc);
err=true;
}
nodes[n.name.name.ptr]=n;
insert(n);
}
foreach(l;topology.links){
auto a=lookupNode(l.a.node),b=lookupNode(l.b.node);
if(a&&b){
void addDirected(InterfaceDecl a,InterfaceDecl b){
auto tpa=tuple(lookupNode(a.node),a.port);
auto tpb=tuple(lookupNode(b.node),b.port,a.loc);
if(tpa in graph){
error(text("multiple links connected to interface ",a),a.loc);
note("previous connection was declared here",graph[tpa][2]);
err=true;
}
graph[tpa]=tpb;
}
addDirected(l.a,l.b);
addDirected(l.b,l.a);
}else err=true;
}
return !err;
}
override FunctionDef getFunction(){ return null; }
}
class PacketFieldScope: Scope{
TopScope top;
override @property ErrorHandler handler(){ return top.handler; }
override @property PacketFieldScope packetFieldScope(){ return this; }
override FunctionDef getFunction(){ return null; }
this(TopScope top){
this.top=top;
}
}
class NestedScope: Scope{
Scope parent;
override @property ErrorHandler handler(){ return parent.handler; }
override @property PacketFieldScope packetFieldScope(){ return parent.packetFieldScope; }
this(Scope parent){ this.parent=parent; }
override Declaration lookup(Identifier ident){
if(auto decl=lookupHere(ident)) return decl;
return parent.lookup(ident);
}
override bool isNestedIn(Scope rhs){ return rhs is this || parent.isNestedIn(rhs); }
override FunctionDef getFunction(){ return parent.getFunction(); }
}
class FunctionScope: NestedScope{
FunctionDef fd;
this(Scope parent,FunctionDef fd){
super(parent);
this.fd=fd;
}
override FunctionDef getFunction(){ return fd; }
}
class BlockScope: NestedScope{
this(Scope parent){ super(parent); }
}
class AggregateScope: NestedScope{
this(Scope parent){ super(parent); }
}