github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/parser/net.go (about) 1 package parser 2 3 import ( 4 "errors" 5 6 "github.com/nevalang/neva/internal/compiler" 7 generated "github.com/nevalang/neva/internal/compiler/parser/generated" 8 src "github.com/nevalang/neva/internal/compiler/sourcecode" 9 "github.com/nevalang/neva/internal/compiler/sourcecode/core" 10 ) 11 12 var ErrEmptyConnDef error = errors.New("Connection must be either normal or array bypass") 13 14 func parseNet(actx generated.IConnDefListContext) ( 15 []src.Connection, 16 *compiler.Error, 17 ) { 18 allConnDefs := actx.AllConnDef() 19 parsedConns := make([]src.Connection, 0, len(allConnDefs)) 20 21 for _, connDef := range allConnDefs { 22 parsedConn, err := parseConn(connDef) 23 if err != nil { 24 return nil, err 25 } 26 parsedConns = append(parsedConns, parsedConn...) 27 } 28 29 return parsedConns, nil 30 } 31 32 func parseConn(connDef generated.IConnDefContext) ( 33 []src.Connection, 34 *compiler.Error, 35 ) { 36 connMeta := core.Meta{ 37 Text: connDef.GetText(), 38 Start: core.Position{ 39 Line: connDef.GetStart().GetLine(), 40 Column: connDef.GetStart().GetColumn(), 41 }, 42 Stop: core.Position{ 43 Line: connDef.GetStop().GetLine(), 44 Column: connDef.GetStop().GetColumn(), 45 }, 46 } 47 48 normConn := connDef.NormConnDef() 49 arrBypassConn := connDef.ArrBypassConnDef() 50 51 if normConn == nil && arrBypassConn == nil { 52 return nil, &compiler.Error{ 53 Err: ErrEmptyConnDef, 54 Meta: &connMeta, 55 } 56 } 57 58 if arrBypassConn != nil { 59 return parseArrayBypassConn(arrBypassConn, connMeta) 60 } 61 62 return parseNormConn(normConn, connMeta) 63 } 64 65 func parseArrayBypassConn(arrBypassConn generated.IArrBypassConnDefContext, connMeta core.Meta) ([]src.Connection, *compiler.Error) { 66 senderPortAddr := arrBypassConn.SinglePortAddr(0) 67 receiverPortAddr := arrBypassConn.SinglePortAddr(1) 68 69 senderPortAddrParsed, err := parseSinglePortAddr( 70 "in", 71 senderPortAddr, 72 connMeta, 73 ) 74 if err != nil { 75 return nil, err 76 } 77 78 receiverPortAddrParsed, err := parseSinglePortAddr( 79 "out", 80 receiverPortAddr, 81 connMeta, 82 ) 83 if err != nil { 84 return nil, err 85 } 86 87 return []src.Connection{ 88 { 89 ArrayBypass: &src.ArrayBypassConnection{ 90 SenderOutport: senderPortAddrParsed, 91 ReceiverInport: receiverPortAddrParsed, 92 }, 93 Meta: connMeta, 94 }, 95 }, nil 96 } 97 98 func parseNormConn( 99 normConn generated.INormConnDefContext, 100 connMeta core.Meta, 101 ) ([]src.Connection, *compiler.Error) { 102 singleSender := normConn.SenderSide().SingleSenderSide() 103 mulSenders := normConn.SenderSide().MultipleSenderSide() 104 105 if singleSender == nil && mulSenders == nil { 106 return nil, &compiler.Error{ 107 Err: errors.New( 108 "Connection must have at least one sender side", 109 ), 110 Meta: &connMeta, 111 } 112 } 113 114 senderSides := []src.ConnectionSenderSide{} 115 if singleSender != nil { 116 parsedSide, err := parseNormConnSenderSide(singleSender) 117 if err != nil { 118 return nil, err 119 } 120 senderSides = append(senderSides, parsedSide) 121 } else { 122 for _, senderSide := range mulSenders.AllSingleSenderSide() { 123 parsedSide, err := parseNormConnSenderSide(senderSide) 124 if err != nil { 125 return nil, err 126 } 127 senderSides = append(senderSides, parsedSide) 128 } 129 } 130 131 receiverSide := normConn.ReceiverSide() 132 chainedConn := receiverSide.ChainedNormConn() 133 singleReceiverSide := receiverSide.SingleReceiverSide() 134 multipleReceiverSide := receiverSide.MultipleReceiverSide() 135 136 if chainedConn == nil && 137 singleReceiverSide == nil && 138 multipleReceiverSide == nil { 139 return nil, &compiler.Error{ 140 Err: errors.New("Connection must have a receiver side"), 141 Meta: &connMeta, 142 } 143 } 144 145 if chainedConn == nil { 146 parsedReceiverSide, extraConns, err := parseNormConnReceiverSide(normConn, connMeta) 147 if err != nil { 148 return nil, compiler.Error{Meta: &connMeta}.Wrap(err) 149 } 150 151 conns := []src.Connection{} 152 for _, senderSide := range senderSides { 153 conns = append(conns, src.Connection{ 154 Normal: &src.NormalConnection{ 155 SenderSide: senderSide, 156 ReceiverSide: parsedReceiverSide, 157 }, 158 Meta: connMeta, 159 }) 160 } 161 162 conns = append(conns, extraConns...) 163 164 return conns, nil 165 } 166 167 // --- chained connection --- 168 169 chainedNormConn := chainedConn.NormConnDef() 170 connMeta = core.Meta{ 171 Text: chainedNormConn.GetText(), 172 Start: core.Position{ 173 Line: chainedNormConn.GetStart().GetLine(), 174 Column: chainedNormConn.GetStart().GetColumn(), 175 }, 176 Stop: core.Position{ 177 Line: chainedNormConn.GetStop().GetLine(), 178 Column: chainedNormConn.GetStop().GetColumn(), 179 }, 180 } 181 182 parseChainConnResult, err := parseNormConn( 183 chainedNormConn, 184 connMeta, 185 ) 186 if err != nil { 187 return nil, err 188 } 189 190 // chain connections always have 1 sender with normal port addr 191 chainSenderPortAddr := parseChainConnResult[0].Normal.SenderSide.PortAddr 192 193 // now we need to connect all senders to the chain sender 194 conns := []src.Connection{} 195 for _, senderSide := range senderSides { 196 conns = append(conns, src.Connection{ 197 Normal: &src.NormalConnection{ 198 SenderSide: senderSide, 199 ReceiverSide: src.ConnectionReceiverSide{ 200 Receivers: []src.ConnectionReceiver{ 201 {PortAddr: *chainSenderPortAddr}, 202 }, 203 }, 204 }, 205 Meta: connMeta, 206 }) 207 } 208 209 // and don't forget the chained connection(s) itself 210 conns = append(conns, parseChainConnResult...) 211 212 return conns, nil 213 } 214 215 func parseNormConnReceiverSide( 216 normConn generated.INormConnDefContext, 217 connMeta core.Meta, 218 ) (src.ConnectionReceiverSide, []src.Connection, *compiler.Error) { 219 receiverSide := normConn.ReceiverSide() 220 singleReceiverSide := receiverSide.SingleReceiverSide() 221 multipleReceiverSide := receiverSide.MultipleReceiverSide() 222 223 if singleReceiverSide == nil && multipleReceiverSide == nil { 224 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 225 Err: errors.New("No receiver side in connection"), 226 Meta: &connMeta, 227 } 228 } 229 230 if singleReceiverSide != nil { 231 return parseReceiverSide(receiverSide, connMeta) 232 } 233 234 multipleSides := receiverSide.MultipleReceiverSide() 235 if multipleSides == nil { 236 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 237 Err: errors.New("no receiver sides at all"), 238 Meta: &core.Meta{ 239 Text: normConn.GetText(), 240 Start: core.Position{ 241 Line: normConn.GetStart().GetLine(), 242 Column: normConn.GetStart().GetColumn(), 243 }, 244 Stop: core.Position{ 245 Line: normConn.GetStop().GetLine(), 246 Column: normConn.GetStop().GetColumn(), 247 }, 248 }, 249 } 250 } 251 252 return parseMultipleReceiverSides(multipleSides) 253 } 254 255 func parseReceiverSide( 256 actx generated.IReceiverSideContext, 257 connMeta core.Meta, 258 ) (src.ConnectionReceiverSide, []src.Connection, *compiler.Error) { 259 deferredConn := actx.SingleReceiverSide().DeferredConn() 260 portAddr := actx.SingleReceiverSide().PortAddr() 261 262 if deferredConn == nil && portAddr == nil { 263 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 264 Err: errors.New("No receiver side in connection"), 265 Meta: &connMeta, 266 } 267 } 268 269 if deferredConn != nil { 270 return parseDeferredConnExpr(deferredConn, connMeta) 271 } 272 273 parsedSingleReceiver, err := parseSingleReceiverSide(portAddr) 274 return parsedSingleReceiver, nil, err 275 } 276 277 func parseMultipleReceiverSides( 278 multipleSides generated.IMultipleReceiverSideContext, 279 ) ( 280 src.ConnectionReceiverSide, 281 []src.Connection, 282 *compiler.Error, 283 ) { 284 allSingleReceiverSides := multipleSides.AllSingleReceiverSide() 285 allParsedReceivers := make([]src.ConnectionReceiver, 0, len(allSingleReceiverSides)) 286 allParsedDeferredConns := make([]src.Connection, 0, len(allSingleReceiverSides)) 287 288 allExtra := []src.Connection{} 289 290 for _, receiverSide := range allSingleReceiverSides { 291 meta := core.Meta{ 292 Text: receiverSide.GetText(), 293 Start: core.Position{ 294 Line: receiverSide.GetStart().GetLine(), 295 Column: receiverSide.GetStart().GetColumn(), 296 }, 297 Stop: core.Position{ 298 Line: receiverSide.GetStop().GetLine(), 299 Column: receiverSide.GetStop().GetColumn(), 300 }, 301 } 302 303 portAddr := receiverSide.PortAddr() 304 deferredConns := receiverSide.DeferredConn() 305 306 if portAddr == nil && deferredConns == nil { 307 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 308 Err: errors.New("No receiver side in connection"), 309 Meta: &meta, 310 } 311 } 312 313 if portAddr != nil { 314 portAddr, err := parsePortAddr(receiverSide.PortAddr(), "out") 315 if err != nil { 316 return src.ConnectionReceiverSide{}, nil, err 317 } 318 allParsedReceivers = append(allParsedReceivers, src.ConnectionReceiver{ 319 PortAddr: portAddr, 320 Meta: meta, 321 }) 322 continue 323 } 324 325 parsedDeferredConns, extra, err := parseDeferredConnExpr(deferredConns, meta) 326 if err != nil { 327 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 328 Err: err, 329 Meta: &meta, 330 } 331 } 332 333 allParsedDeferredConns = append(allParsedDeferredConns, parsedDeferredConns.DeferredConnections...) 334 allExtra = append(allExtra, extra...) 335 } 336 337 return src.ConnectionReceiverSide{ 338 Receivers: allParsedReceivers, 339 DeferredConnections: allParsedDeferredConns, 340 }, allExtra, nil 341 } 342 343 func parseDeferredConnExpr( 344 deferredConns generated.IDeferredConnContext, 345 connMeta core.Meta, 346 ) (src.ConnectionReceiverSide, []src.Connection, *compiler.Error) { 347 parsedConns, err := parseConn(deferredConns.ConnDef()) 348 if err != nil { 349 return src.ConnectionReceiverSide{}, nil, &compiler.Error{ 350 Err: err, 351 Meta: &connMeta, 352 } 353 } 354 355 if len(parsedConns) == 1 { 356 return src.ConnectionReceiverSide{ 357 DeferredConnections: parsedConns, 358 }, nil, nil 359 } 360 361 // if we have >1 then there was chained connection inside 362 return src.ConnectionReceiverSide{ 363 DeferredConnections: parsedConns[:1], 364 }, parsedConns[1:], nil 365 } 366 367 func parseNormConnSenderSide( 368 senderSide generated.ISingleSenderSideContext, 369 ) (src.ConnectionSenderSide, *compiler.Error) { //nolint:funlen 370 var senderSelectors []string 371 singleSenderSelectors := senderSide.StructSelectors() 372 if singleSenderSelectors != nil { 373 for _, id := range singleSenderSelectors.AllIDENTIFIER() { 374 senderSelectors = append(senderSelectors, id.GetText()) 375 } 376 } 377 378 portSender := senderSide.PortAddr() 379 constRefSender := senderSide.SenderConstRef() 380 primitiveConstLitSender := senderSide.PrimitiveConstLit() 381 382 if portSender == nil && 383 constRefSender == nil && 384 primitiveConstLitSender == nil { 385 return src.ConnectionSenderSide{}, &compiler.Error{ 386 Err: errors.New("Sender side is missing in connection"), 387 Meta: &core.Meta{ 388 Text: senderSide.GetText(), 389 Start: core.Position{ 390 Line: senderSide.GetStart().GetLine(), 391 Column: senderSide.GetStart().GetColumn(), 392 }, 393 Stop: core.Position{ 394 Line: senderSide.GetStop().GetLine(), 395 Column: senderSide.GetStop().GetColumn(), 396 }, 397 }, 398 } 399 } 400 401 var senderSidePortAddr *src.PortAddr 402 if portSender != nil { 403 parsedPortAddr, err := parsePortAddr(portSender, "in") 404 if err != nil { 405 return src.ConnectionSenderSide{}, err 406 } 407 senderSidePortAddr = &parsedPortAddr 408 } 409 410 var constant *src.Const 411 if constRefSender != nil { 412 parsedEntityRef, err := parseEntityRef(constRefSender.EntityRef()) 413 if err != nil { 414 return src.ConnectionSenderSide{}, err 415 } 416 constant = &src.Const{ 417 Ref: &parsedEntityRef, 418 } 419 } 420 421 if primitiveConstLitSender != nil { 422 msg, err := parsePrimitiveConstLiteral(primitiveConstLitSender) 423 if err != nil { 424 return src.ConnectionSenderSide{}, err 425 } 426 constant = &src.Const{Message: &msg} 427 } 428 429 parsedSenderSide := src.ConnectionSenderSide{ 430 PortAddr: senderSidePortAddr, 431 Const: constant, 432 Selectors: senderSelectors, 433 Meta: core.Meta{ 434 Text: senderSide.GetText(), 435 Start: core.Position{ 436 Line: senderSide.GetStart().GetLine(), 437 Column: senderSide.GetStart().GetColumn(), 438 }, 439 Stop: core.Position{ 440 Line: senderSide.GetStop().GetLine(), 441 Column: senderSide.GetStop().GetColumn(), 442 }, 443 }, 444 } 445 446 return parsedSenderSide, nil 447 } 448 449 func parseSingleReceiverSide( 450 singleReceiver generated.IPortAddrContext, 451 ) ( 452 src.ConnectionReceiverSide, 453 *compiler.Error, 454 ) { 455 portAddr, err := parsePortAddr(singleReceiver, "out") 456 if err != nil { 457 return src.ConnectionReceiverSide{}, err 458 } 459 460 return src.ConnectionReceiverSide{ 461 Receivers: []src.ConnectionReceiver{ 462 { 463 PortAddr: portAddr, 464 Meta: core.Meta{ 465 Text: singleReceiver.GetText(), 466 Start: core.Position{ 467 Line: singleReceiver.GetStart().GetLine(), 468 Column: singleReceiver.GetStart().GetColumn(), 469 }, 470 Stop: core.Position{ 471 Line: singleReceiver.GetStop().GetLine(), 472 Column: singleReceiver.GetStop().GetColumn(), 473 }, 474 }, 475 }, 476 }, 477 }, nil 478 } 479 480 // :start -> (99 -> next:n -> match:data) 481 482 // :start -> (99 -> next:n, next:n -> match:data) 483 484 // :start -> (99 -> next:n) 485 // next:n -> match:data