github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/parser/listener_helpers.go (about) 1 package parser 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 9 "github.com/antlr4-go/antlr/v4" 10 "github.com/nevalang/neva/internal/compiler" 11 generated "github.com/nevalang/neva/internal/compiler/parser/generated" 12 src "github.com/nevalang/neva/internal/compiler/sourcecode" 13 "github.com/nevalang/neva/internal/compiler/sourcecode/core" 14 ts "github.com/nevalang/neva/internal/compiler/sourcecode/typesystem" 15 ) 16 17 func parseTypeParams( 18 params generated.ITypeParamsContext, 19 ) (src.TypeParams, *compiler.Error) { 20 if params == nil || params.TypeParamList() == nil { 21 return src.TypeParams{}, nil 22 } 23 24 typeParams := params.TypeParamList().AllTypeParam() 25 result := make([]ts.Param, 0, len(typeParams)) 26 for _, typeParam := range typeParams { 27 v, err := parseTypeExpr(typeParam.TypeExpr()) 28 if err != nil { 29 return src.TypeParams{}, err 30 } 31 result = append(result, ts.Param{ 32 Name: typeParam.IDENTIFIER().GetText(), 33 Constr: v, 34 }) 35 } 36 37 return src.TypeParams{ 38 Params: result, 39 Meta: core.Meta{ 40 Text: params.GetText(), 41 Start: core.Position{ 42 Line: params.GetStart().GetLine(), 43 Column: params.GetStart().GetColumn(), 44 }, 45 Stop: core.Position{ 46 Line: params.GetStop().GetLine(), 47 Column: params.GetStop().GetColumn(), 48 }, 49 }, 50 }, nil 51 } 52 53 func parseTypeExpr(expr generated.ITypeExprContext) (ts.Expr, *compiler.Error) { 54 if expr == nil { 55 return ts.Expr{ 56 Inst: &ts.InstExpr{ 57 Ref: core.EntityRef{Name: "any"}, 58 }, 59 Meta: core.Meta{Text: "any"}, 60 }, nil 61 } 62 63 var result *ts.Expr 64 if instExpr := expr.TypeInstExpr(); instExpr != nil { 65 v, err := parseTypeInstExpr(instExpr) 66 if err != nil { 67 return ts.Expr{}, &compiler.Error{ 68 Err: err, 69 Meta: &core.Meta{ 70 Text: expr.GetText(), 71 Start: core.Position{ 72 Line: expr.GetStart().GetLine(), 73 Column: expr.GetStart().GetColumn(), 74 }, 75 Stop: core.Position{ 76 Line: expr.GetStop().GetLine(), 77 Column: expr.GetStop().GetColumn(), 78 }, 79 }, 80 } 81 } 82 result = v 83 } else if unionExpr := expr.UnionTypeExpr(); unionExpr != nil { 84 v, err := parseUnionExpr(unionExpr) 85 if err != nil { 86 return ts.Expr{}, err 87 } 88 result = v 89 } else if litExpr := expr.TypeLitExpr(); litExpr != nil { 90 v, err := parseLitExpr(litExpr) 91 if err != nil { 92 return ts.Expr{}, err 93 } 94 result = v 95 } else { 96 return ts.Expr{}, &compiler.Error{ 97 Err: errors.New("Missing type expression"), 98 Meta: &core.Meta{ 99 Text: expr.GetText(), 100 Start: core.Position{ 101 Line: expr.GetStart().GetLine(), 102 Column: expr.GetStart().GetLine(), 103 }, 104 Stop: core.Position{ 105 Line: expr.GetStop().GetLine(), 106 Column: expr.GetStop().GetLine(), 107 }, 108 }, 109 } 110 } 111 112 result.Meta = getTypeExprMeta(expr) 113 114 return *result, nil 115 } 116 117 func getTypeExprMeta(expr generated.ITypeExprContext) core.Meta { 118 var text string 119 if text = expr.GetText(); text == "" { 120 text = "any " 121 } 122 123 start := expr.GetStart() 124 stop := expr.GetStop() 125 meta := core.Meta{ 126 Text: text, 127 Start: core.Position{ 128 Line: start.GetLine(), 129 Column: start.GetColumn(), 130 }, 131 Stop: core.Position{ 132 Line: stop.GetLine(), 133 Column: stop.GetColumn(), 134 }, 135 } 136 return meta 137 } 138 139 func parseUnionExpr(unionExpr generated.IUnionTypeExprContext) (*ts.Expr, *compiler.Error) { 140 subExprs := unionExpr.AllNonUnionTypeExpr() 141 parsedSubExprs := make([]ts.Expr, 0, len(subExprs)) 142 143 for _, subExpr := range subExprs { 144 if instExpr := subExpr.TypeInstExpr(); instExpr != nil { 145 parsedTypeInstExpr, err := parseTypeInstExpr(instExpr) 146 if err != nil { 147 return nil, err 148 } 149 parsedSubExprs = append(parsedSubExprs, *parsedTypeInstExpr) 150 } 151 if unionExpr := subExpr.TypeLitExpr(); unionExpr != nil { 152 v, err := parseLitExpr(subExpr.TypeLitExpr()) 153 if err != nil { 154 return nil, err 155 } 156 parsedSubExprs = append(parsedSubExprs, *v) 157 } 158 } 159 160 return &ts.Expr{ 161 Lit: &ts.LitExpr{ 162 Union: parsedSubExprs, 163 }, 164 }, nil 165 } 166 167 func parseLitExpr(litExpr generated.ITypeLitExprContext) (*ts.Expr, *compiler.Error) { 168 enumExpr := litExpr.EnumTypeExpr() 169 structExpr := litExpr.StructTypeExpr() 170 171 switch { 172 case enumExpr != nil: 173 return parseEnumExpr(enumExpr), nil 174 case structExpr != nil: 175 return parseStructExpr(structExpr) 176 } 177 178 return nil, &compiler.Error{ 179 Err: errors.New("Unknown literal type"), 180 Meta: &core.Meta{ 181 Text: litExpr.GetText(), 182 Start: core.Position{ 183 Line: litExpr.GetStart().GetLine(), 184 Column: litExpr.GetStart().GetColumn(), 185 }, 186 Stop: core.Position{ 187 Line: litExpr.GetStop().GetLine(), 188 Column: litExpr.GetStop().GetColumn(), 189 }, 190 }, 191 } 192 } 193 194 func parseEnumExpr(enumExpr generated.IEnumTypeExprContext) *ts.Expr { 195 ids := enumExpr.AllIDENTIFIER() 196 result := ts.Expr{ 197 Lit: &ts.LitExpr{ 198 Enum: make([]string, 0, len(ids)), 199 }, 200 } 201 for _, id := range ids { 202 result.Lit.Enum = append(result.Lit.Enum, id.GetText()) 203 } 204 return &result 205 } 206 207 func parseStructExpr( 208 structExpr generated.IStructTypeExprContext, 209 ) (*ts.Expr, *compiler.Error) { 210 result := ts.Expr{ 211 Lit: &ts.LitExpr{ 212 Struct: map[string]ts.Expr{}, 213 }, 214 } 215 216 structFields := structExpr.StructFields() 217 if structFields == nil { 218 return &result, nil 219 } 220 221 fields := structExpr.StructFields().AllStructField() 222 result.Lit.Struct = make(map[string]ts.Expr, len(fields)) 223 224 for _, field := range fields { 225 fieldName := field.IDENTIFIER().GetText() 226 v, err := parseTypeExpr(field.TypeExpr()) 227 if err != nil { 228 return nil, err 229 } 230 result.Lit.Struct[fieldName] = v 231 } 232 233 return &result, nil 234 } 235 236 func parseTypeInstExpr(instExpr generated.ITypeInstExprContext) (*ts.Expr, *compiler.Error) { 237 parsedRef, err := parseEntityRef(instExpr.EntityRef()) 238 if err != nil { 239 return nil, &compiler.Error{ 240 Err: err, 241 Meta: &core.Meta{ 242 Text: instExpr.GetText(), 243 Start: core.Position{ 244 Line: instExpr.GetStart().GetLine(), 245 Column: instExpr.GetStart().GetColumn(), 246 }, 247 Stop: core.Position{ 248 Line: instExpr.GetStop().GetLine(), 249 Column: instExpr.GetStop().GetColumn(), 250 }, 251 }, 252 } 253 } 254 255 result := ts.Expr{ 256 Inst: &ts.InstExpr{ 257 Ref: parsedRef, 258 }, 259 } 260 261 args := instExpr.TypeArgs() 262 if args == nil { 263 return &result, nil 264 } 265 266 argExprs := args.AllTypeExpr() 267 parsedArgs := make([]ts.Expr, 0, len(argExprs)) 268 for _, arg := range argExprs { 269 v, err := parseTypeExpr(arg) 270 if err != nil { 271 return nil, err 272 } 273 parsedArgs = append(parsedArgs, v) 274 } 275 result.Inst.Args = parsedArgs 276 277 return &result, nil 278 } 279 280 func parseEntityRef(expr generated.IEntityRefContext) (core.EntityRef, *compiler.Error) { 281 meta := core.Meta{ 282 Text: expr.GetText(), 283 Start: core.Position{ 284 Line: expr.GetStart().GetLine(), 285 Column: expr.GetStart().GetColumn(), 286 }, 287 Stop: core.Position{ 288 Line: expr.GetStart().GetLine(), 289 Column: expr.GetStop().GetColumn(), 290 }, 291 } 292 293 parts := strings.Split(expr.GetText(), ".") 294 if len(parts) > 2 { 295 return core.EntityRef{}, &compiler.Error{ 296 Err: fmt.Errorf("Invalid entity reference %v", expr.GetText()), 297 Meta: &meta, 298 } 299 } 300 301 if len(parts) == 1 { 302 return core.EntityRef{ 303 Name: parts[0], 304 Meta: meta, 305 }, nil 306 } 307 308 return core.EntityRef{ 309 Pkg: parts[0], 310 Name: parts[1], 311 Meta: meta, 312 }, nil 313 } 314 315 func parsePorts( 316 in []generated.IPortDefContext, 317 ) (map[string]src.Port, *compiler.Error) { 318 parsedInports := map[string]src.Port{} 319 for _, port := range in { 320 single := port.SinglePortDef() 321 arr := port.ArrayPortDef() 322 323 var ( 324 id antlr.TerminalNode 325 typeExpr generated.ITypeExprContext 326 isArr bool 327 ) 328 if single != nil { 329 isArr = false 330 id = single.IDENTIFIER() 331 typeExpr = single.TypeExpr() 332 } else { 333 isArr = true 334 id = arr.IDENTIFIER() 335 typeExpr = arr.TypeExpr() 336 } 337 338 portName := id.GetText() 339 v, err := parseTypeExpr(typeExpr) 340 if err != nil { 341 return nil, err 342 } 343 parsedInports[portName] = src.Port{ 344 IsArray: isArr, 345 TypeExpr: v, 346 Meta: core.Meta{ 347 Text: port.GetText(), 348 Start: core.Position{ 349 Line: port.GetStart().GetLine(), 350 Column: port.GetStart().GetColumn(), 351 }, 352 Stop: core.Position{ 353 Line: port.GetStop().GetLine(), 354 Column: port.GetStop().GetColumn(), 355 }, 356 }, 357 } 358 } 359 360 return parsedInports, nil 361 } 362 363 func parseInterfaceDef( 364 actx generated.IInterfaceDefContext, 365 ) (src.Interface, *compiler.Error) { 366 parsedTypeParams, err := parseTypeParams(actx.TypeParams()) 367 if err != nil { 368 return src.Interface{}, err 369 } 370 in, err := parsePorts(actx.InPortsDef().PortsDef().AllPortDef()) 371 if err != nil { 372 return src.Interface{}, err 373 } 374 out, err := parsePorts(actx.OutPortsDef().PortsDef().AllPortDef()) 375 if err != nil { 376 return src.Interface{}, err 377 } 378 379 return src.Interface{ 380 TypeParams: parsedTypeParams, 381 IO: src.IO{In: in, Out: out}, 382 Meta: core.Meta{ 383 Text: actx.GetText(), 384 Start: core.Position{ 385 Line: actx.GetStart().GetLine(), 386 Column: actx.GetStart().GetColumn(), 387 }, 388 Stop: core.Position{ 389 Line: actx.GetStop().GetLine(), 390 Column: actx.GetStop().GetColumn(), 391 }, 392 }, 393 }, nil 394 } 395 396 func parseNodes( 397 actx generated.ICompNodesDefBodyContext, 398 isRootLevel bool, 399 ) (map[string]src.Node, *compiler.Error) { 400 result := map[string]src.Node{} 401 402 for _, node := range actx.AllCompNodeDef() { 403 nodeInst := node.NodeInst() 404 405 directives := parseCompilerDirectives(node.CompilerDirectives()) 406 407 parsedRef, err := parseEntityRef(nodeInst.EntityRef()) 408 if err != nil { 409 return nil, &compiler.Error{ 410 Err: err, 411 Meta: &core.Meta{ 412 Text: node.GetText(), 413 Start: core.Position{ 414 Line: node.GetStart().GetLine(), 415 Column: node.GetStart().GetColumn(), 416 }, 417 Stop: core.Position{ 418 Line: node.GetStop().GetLine(), 419 Column: node.GetStop().GetColumn(), 420 }, 421 }, 422 } 423 } 424 425 var typeArgs []ts.Expr 426 if args := nodeInst.TypeArgs(); args != nil { 427 v, err := parseTypeExprs(args.AllTypeExpr()) 428 if err != nil { 429 return nil, err 430 } 431 typeArgs = v 432 } 433 434 var errGuard bool 435 if nodeInst.ErrGuard() != nil { 436 errGuard = true 437 } 438 439 var deps map[string]src.Node 440 if diArgs := nodeInst.NodeDIArgs(); diArgs != nil { 441 v, err := parseNodes(diArgs.CompNodesDefBody(), false) 442 if err != nil { 443 return nil, err 444 } 445 deps = v 446 } 447 448 var nodeName string 449 if id := node.IDENTIFIER(); id != nil { 450 nodeName = id.GetText() 451 } else if isRootLevel { 452 nodeName = strings.ToLower(string(parsedRef.Name[0])) + parsedRef.Name[1:] 453 } 454 455 result[nodeName] = src.Node{ 456 Directives: directives, 457 EntityRef: parsedRef, 458 TypeArgs: typeArgs, 459 ErrGuard: errGuard, 460 Deps: deps, 461 Meta: core.Meta{ 462 Text: node.GetText(), 463 Start: core.Position{ 464 Line: node.GetStart().GetLine(), 465 Column: node.GetStart().GetColumn(), 466 }, 467 Stop: core.Position{ 468 Line: node.GetStop().GetLine(), 469 Column: node.GetStop().GetColumn(), 470 }, 471 }, 472 } 473 } 474 475 return result, nil 476 } 477 478 func parseTypeExprs( 479 in []generated.ITypeExprContext, 480 ) ([]ts.Expr, *compiler.Error) { 481 result := make([]ts.Expr, 0, len(in)) 482 483 for _, expr := range in { 484 v, err := parseTypeExpr(expr) 485 if err != nil { 486 return nil, err 487 } 488 result = append(result, v) 489 } 490 491 return result, nil 492 } 493 494 func parsePortAddr( 495 expr generated.IPortAddrContext, 496 fallbackNode string, 497 ) (src.PortAddr, *compiler.Error) { 498 meta := core.Meta{ 499 Text: expr.GetText(), 500 Start: core.Position{ 501 Line: expr.GetStart().GetLine(), 502 Column: expr.GetStart().GetColumn(), 503 }, 504 Stop: core.Position{ 505 Line: expr.GetStart().GetLine(), 506 Column: expr.GetStop().GetColumn(), 507 }, 508 } 509 510 if expr.ArrPortAddr() == nil && 511 expr.SinglePortAddr() == nil && 512 expr.LonelySinglePortAddr() == nil && 513 expr.LonelyArrPortAddr() == nil { 514 return src.PortAddr{}, &compiler.Error{ 515 Err: fmt.Errorf("Invalid port address %v", expr.GetText()), 516 Meta: &meta, 517 } 518 } 519 520 if expr.LonelyArrPortAddr() != nil { 521 idxStr := expr.LonelyArrPortAddr().PortAddrIdx() 522 withoutSquareBraces := strings.Trim(idxStr.GetText(), "[]") 523 524 idxUint, err := strconv.ParseUint( 525 withoutSquareBraces, 526 10, 527 8, 528 ) 529 if err != nil { 530 return src.PortAddr{}, &compiler.Error{ 531 Err: err, 532 Meta: &meta, 533 } 534 } 535 536 idxUint8 := uint8(idxUint) 537 538 return src.PortAddr{ 539 Node: expr.LonelyArrPortAddr().PortAddrNode().GetText(), 540 Port: "", 541 Idx: &idxUint8, 542 Meta: meta, 543 }, nil 544 } 545 546 if expr.LonelySinglePortAddr() != nil { 547 return src.PortAddr{ 548 Node: expr.LonelySinglePortAddr().PortAddrNode().GetText(), 549 Port: "", 550 // Idx: &idxUint8, 551 Meta: meta, 552 }, nil 553 } 554 555 if expr.SinglePortAddr() != nil { 556 return parseSinglePortAddr(fallbackNode, expr.SinglePortAddr(), meta) 557 } 558 559 idxStr := expr.ArrPortAddr().PortAddrIdx() 560 withoutSquareBraces := strings.Trim(idxStr.GetText(), "[]") 561 562 idxUint, err := strconv.ParseUint( 563 withoutSquareBraces, 564 10, 565 8, 566 ) 567 if err != nil { 568 return src.PortAddr{}, &compiler.Error{ 569 Err: err, 570 Meta: &meta, 571 } 572 } 573 574 nodeName := fallbackNode 575 if n := expr.ArrPortAddr().PortAddrNode(); n != nil { 576 nodeName = n.GetText() 577 } 578 579 idxUint8 := uint8(idxUint) 580 581 return src.PortAddr{ 582 Idx: &idxUint8, 583 Node: nodeName, 584 Port: expr.ArrPortAddr().PortAddrPort().GetText(), 585 Meta: meta, 586 }, nil 587 588 } 589 590 func parseSinglePortAddr( 591 fallbackNode string, 592 expr generated.ISinglePortAddrContext, 593 meta core.Meta, 594 ) (src.PortAddr, *compiler.Error) { 595 nodeName := fallbackNode 596 if n := expr.PortAddrNode(); n != nil { 597 nodeName = n.GetText() 598 } 599 600 return src.PortAddr{ 601 Node: nodeName, 602 Port: expr.PortAddrPort().GetText(), 603 Meta: meta, 604 }, nil 605 } 606 607 func parsePrimitiveConstLiteral( 608 lit generated.IPrimitiveConstLitContext, 609 ) (src.Message, *compiler.Error) { 610 msg := src.Message{ 611 Meta: core.Meta{ 612 Text: lit.GetText(), 613 Start: core.Position{ 614 Line: lit.GetStart().GetLine(), 615 Column: lit.GetStart().GetColumn(), 616 }, 617 Stop: core.Position{ 618 Line: lit.GetStop().GetLine(), 619 Column: lit.GetStop().GetColumn(), 620 }, 621 }, 622 } 623 624 switch { 625 case lit.Bool_() != nil: 626 boolVal := lit.Bool_().GetText() 627 if boolVal != "true" && boolVal != "false" { 628 return src.Message{}, &compiler.Error{ 629 Err: fmt.Errorf("Invalid boolean value %v", boolVal), 630 Meta: &core.Meta{ 631 Text: lit.GetText(), 632 Start: core.Position{ 633 Line: lit.GetStart().GetLine(), 634 Column: lit.GetStart().GetColumn(), 635 }, 636 Stop: core.Position{ 637 Line: lit.GetStop().GetLine(), 638 Column: lit.GetStop().GetColumn(), 639 }, 640 }, 641 } 642 } 643 msg.TypeExpr.Inst = &ts.InstExpr{ 644 Ref: core.EntityRef{Name: "bool"}, 645 } 646 msg.Bool = compiler.Pointer(boolVal == "true") 647 case lit.INT() != nil: 648 parsedInt, err := strconv.ParseInt(lit.INT().GetText(), 10, 64) 649 if err != nil { 650 return src.Message{}, &compiler.Error{ 651 Err: err, 652 Location: &src.Location{}, 653 Meta: &core.Meta{ 654 Text: lit.GetText(), 655 Start: core.Position{ 656 Line: lit.GetStart().GetLine(), 657 Column: lit.GetStart().GetColumn(), 658 }, 659 Stop: core.Position{ 660 Line: lit.GetStop().GetLine(), 661 Column: lit.GetStop().GetColumn(), 662 }, 663 }, 664 } 665 } 666 msg.TypeExpr.Inst = &ts.InstExpr{ 667 Ref: core.EntityRef{Name: "int"}, 668 } 669 if lit.MINUS() != nil { 670 parsedInt = -parsedInt 671 } 672 msg.Int = compiler.Pointer(int(parsedInt)) 673 case lit.FLOAT() != nil: 674 parsedFloat, err := strconv.ParseFloat(lit.FLOAT().GetText(), 64) 675 if err != nil { 676 return src.Message{}, &compiler.Error{ 677 Err: err, 678 Meta: &core.Meta{ 679 Text: lit.GetText(), 680 Start: core.Position{ 681 Line: lit.GetStart().GetLine(), 682 Column: lit.GetStart().GetColumn(), 683 }, 684 Stop: core.Position{ 685 Line: lit.GetStop().GetLine(), 686 Column: lit.GetStop().GetColumn(), 687 }, 688 }, 689 } 690 } 691 msg.TypeExpr.Inst = &ts.InstExpr{ 692 Ref: core.EntityRef{Name: "float"}, 693 } 694 if lit.MINUS() != nil { 695 parsedFloat = -parsedFloat 696 } 697 msg.Float = &parsedFloat 698 case lit.STRING() != nil: 699 msg.Str = compiler.Pointer( 700 strings.Trim( 701 strings.ReplaceAll( 702 lit.STRING().GetText(), 703 "\\n", 704 "\n", 705 ), 706 "'", 707 ), 708 ) 709 msg.TypeExpr.Inst = &ts.InstExpr{ 710 Ref: core.EntityRef{Name: "string"}, 711 } 712 case lit.EnumLit() != nil: 713 parsedEnumRef, err := parseEntityRef(lit.EnumLit().EntityRef()) 714 if err != nil { 715 return src.Message{}, err 716 } 717 msg.Enum = &src.EnumMessage{ 718 EnumRef: parsedEnumRef, 719 MemberName: lit.EnumLit().IDENTIFIER().GetText(), 720 } 721 msg.TypeExpr = ts.Expr{ 722 Inst: &ts.InstExpr{Ref: parsedEnumRef}, 723 Meta: parsedEnumRef.Meta, 724 } 725 case lit.Nil_() != nil: 726 return src.Message{}, nil 727 default: 728 panic("unknown const: " + lit.GetText()) 729 } 730 731 return msg, nil 732 } 733 734 func parseMessage( 735 constVal generated.IConstLitContext, 736 ) (src.Message, *compiler.Error) { 737 msg := src.Message{ 738 Meta: core.Meta{ 739 Text: constVal.GetText(), 740 Start: core.Position{ 741 Line: constVal.GetStart().GetLine(), 742 Column: constVal.GetStart().GetColumn(), 743 }, 744 Stop: core.Position{ 745 Line: constVal.GetStop().GetLine(), 746 Column: constVal.GetStop().GetColumn(), 747 }, 748 }, 749 } 750 751 switch { 752 case constVal.Bool_() != nil: 753 boolVal := constVal.Bool_().GetText() 754 if boolVal != "true" && boolVal != "false" { 755 return src.Message{}, &compiler.Error{ 756 Err: fmt.Errorf("Invalid boolean value %v", boolVal), 757 Meta: &core.Meta{ 758 Text: constVal.GetText(), 759 Start: core.Position{ 760 Line: constVal.GetStart().GetLine(), 761 Column: constVal.GetStart().GetColumn(), 762 }, 763 Stop: core.Position{ 764 Line: constVal.GetStop().GetLine(), 765 Column: constVal.GetStop().GetColumn(), 766 }, 767 }, 768 } 769 } 770 msg.TypeExpr.Inst = &ts.InstExpr{ 771 Ref: core.EntityRef{Name: "bool"}, 772 } 773 msg.Bool = compiler.Pointer(boolVal == "true") 774 case constVal.INT() != nil: 775 parsedInt, err := strconv.ParseInt(constVal.INT().GetText(), 10, 64) 776 if err != nil { 777 return src.Message{}, &compiler.Error{ 778 Err: err, 779 Location: &src.Location{}, 780 Meta: &core.Meta{ 781 Text: constVal.GetText(), 782 Start: core.Position{ 783 Line: constVal.GetStart().GetLine(), 784 Column: constVal.GetStart().GetColumn(), 785 }, 786 Stop: core.Position{ 787 Line: constVal.GetStop().GetLine(), 788 Column: constVal.GetStop().GetColumn(), 789 }, 790 }, 791 } 792 } 793 msg.TypeExpr.Inst = &ts.InstExpr{ 794 Ref: core.EntityRef{Name: "int"}, 795 } 796 if constVal.MINUS() != nil { 797 parsedInt = -parsedInt 798 } 799 msg.Int = compiler.Pointer(int(parsedInt)) 800 case constVal.FLOAT() != nil: 801 parsedFloat, err := strconv.ParseFloat(constVal.FLOAT().GetText(), 64) 802 if err != nil { 803 return src.Message{}, &compiler.Error{ 804 Err: err, 805 Meta: &core.Meta{ 806 Text: constVal.GetText(), 807 Start: core.Position{ 808 Line: constVal.GetStart().GetLine(), 809 Column: constVal.GetStart().GetColumn(), 810 }, 811 Stop: core.Position{ 812 Line: constVal.GetStop().GetLine(), 813 Column: constVal.GetStop().GetColumn(), 814 }, 815 }, 816 } 817 } 818 msg.TypeExpr.Inst = &ts.InstExpr{ 819 Ref: core.EntityRef{Name: "float"}, 820 } 821 if constVal.MINUS() != nil { 822 parsedFloat = -parsedFloat 823 } 824 msg.Float = &parsedFloat 825 case constVal.STRING() != nil: 826 msg.Str = compiler.Pointer( 827 strings.Trim( 828 strings.ReplaceAll( 829 constVal.STRING().GetText(), 830 "\\n", 831 "\n", 832 ), 833 "'", 834 ), 835 ) 836 msg.TypeExpr.Inst = &ts.InstExpr{ 837 Ref: core.EntityRef{Name: "string"}, 838 } 839 case constVal.EnumLit() != nil: 840 parsedEnumRef, err := parseEntityRef(constVal.EnumLit().EntityRef()) 841 if err != nil { 842 return src.Message{}, err 843 } 844 msg.Enum = &src.EnumMessage{ 845 EnumRef: parsedEnumRef, 846 MemberName: constVal.EnumLit().IDENTIFIER().GetText(), 847 } 848 msg.TypeExpr = ts.Expr{ 849 Inst: &ts.InstExpr{Ref: parsedEnumRef}, 850 Meta: parsedEnumRef.Meta, 851 } 852 case constVal.ListLit() != nil: 853 listItems := constVal.ListLit().ListItems() 854 if listItems == nil { // empty list [] 855 msg.List = []src.Const{} 856 return src.Message{}, nil 857 } 858 items := listItems.AllCompositeItem() 859 msg.List = make([]src.Const, 0, len(items)) 860 for _, item := range items { 861 constant := src.Const{ 862 Meta: core.Meta{ 863 Text: item.GetText(), 864 Start: core.Position{ 865 Line: item.GetStart().GetLine(), 866 Column: item.GetStart().GetLine(), 867 }, 868 Stop: core.Position{ 869 Line: item.GetStop().GetLine(), 870 Column: item.GetStop().GetLine(), 871 }, 872 }, 873 } 874 if item.EntityRef() != nil { 875 parsedRef, err := parseEntityRef(item.EntityRef()) 876 if err != nil { 877 return src.Message{}, err 878 } 879 constant.Ref = &parsedRef 880 } else { 881 parsedConstValue, err := parseMessage(item.ConstLit()) 882 if err != nil { 883 return src.Message{}, err 884 } 885 constant.Message = &parsedConstValue 886 887 } 888 msg.List = append(msg.List, constant) 889 } 890 case constVal.StructLit() != nil: 891 fields := constVal.StructLit().StructValueFields() 892 if fields == nil { // empty struct {} 893 msg.MapOrStruct = map[string]src.Const{} 894 return msg, nil 895 } 896 fieldValues := fields.AllStructValueField() 897 msg.MapOrStruct = make(map[string]src.Const, len(fieldValues)) 898 for _, field := range fieldValues { 899 if field.IDENTIFIER() == nil { 900 panic("field.GetText()") 901 } 902 name := field.IDENTIFIER().GetText() 903 if field.CompositeItem().EntityRef() != nil { 904 parsedRef, err := parseEntityRef(field.CompositeItem().EntityRef()) 905 if err != nil { 906 return src.Message{}, err 907 } 908 msg.MapOrStruct[name] = src.Const{ 909 Ref: &parsedRef, 910 } 911 } else { 912 value, err := parseMessage(field.CompositeItem().ConstLit()) 913 if err != nil { 914 return src.Message{}, err 915 } 916 msg.MapOrStruct[name] = src.Const{ 917 Message: &value, 918 } 919 } 920 } 921 case constVal.Nil_() != nil: 922 return src.Message{}, nil 923 default: 924 panic("unknown const: " + constVal.GetText()) 925 } 926 927 return msg, nil 928 } 929 930 func parseCompilerDirectives(actx generated.ICompilerDirectivesContext) map[src.Directive][]string { 931 if actx == nil { 932 return nil 933 } 934 935 directives := actx.AllCompilerDirective() 936 result := make(map[src.Directive][]string, len(directives)) 937 for _, directive := range directives { 938 id := directive.IDENTIFIER() 939 if directive.CompilerDirectivesArgs() == nil { 940 result[src.Directive(id.GetText())] = []string{} 941 continue 942 } 943 args := directive.CompilerDirectivesArgs().AllCompiler_directive_arg() 944 ss := make([]string, 0, len(args)) 945 for _, arg := range args { 946 s := "" 947 ids := arg.AllIDENTIFIER() 948 for i, id := range ids { 949 s += id.GetText() 950 if i < len(ids)-1 { 951 s += " " 952 } 953 } 954 ss = append(ss, s) 955 } 956 result[src.Directive(id.GetText())] = ss 957 } 958 959 return result 960 } 961 962 func parseTypeDef( 963 actx generated.ITypeDefContext, 964 ) (src.Entity, *compiler.Error) { 965 var body *ts.Expr 966 if expr := actx.TypeExpr(); expr != nil { 967 v, err := parseTypeExpr(actx.TypeExpr()) 968 if err != nil { 969 return src.Entity{}, err 970 } 971 body = compiler.Pointer(v) 972 } 973 974 v, err := parseTypeParams(actx.TypeParams()) 975 if err != nil { 976 return src.Entity{}, err 977 } 978 979 return src.Entity{ 980 Kind: src.TypeEntity, 981 Type: ts.Def{ 982 Params: v.Params, 983 BodyExpr: body, 984 // CanBeUsedForRecursiveDefinitions: body == nil, 985 Meta: core.Meta{ 986 Text: actx.GetText(), 987 Start: core.Position{ 988 Line: actx.GetStart().GetLine(), 989 Column: actx.GetStart().GetColumn(), 990 }, 991 Stop: core.Position{ 992 Line: actx.GetStop().GetLine(), 993 Column: actx.GetStop().GetColumn(), 994 }, 995 }, 996 }, 997 }, nil 998 } 999 1000 func parseConstDef( 1001 actx generated.IConstDefContext, 1002 ) (src.Entity, *compiler.Error) { 1003 constVal := actx.ConstLit() 1004 entityRef := actx.EntityRef() 1005 1006 if constVal == nil && entityRef == nil { 1007 panic("constVal == nil && entityRef == nil") 1008 } 1009 1010 meta := core.Meta{ 1011 Text: actx.GetText(), 1012 Start: core.Position{ 1013 Line: actx.GetStart().GetLine(), 1014 Column: actx.GetStart().GetColumn(), 1015 }, 1016 Stop: core.Position{ 1017 Line: actx.GetStop().GetLine(), 1018 Column: actx.GetStop().GetColumn(), 1019 }, 1020 } 1021 1022 var parsedConst src.Const 1023 1024 if entityRef != nil { 1025 parsedRef, err := parseEntityRef(entityRef) 1026 if err != nil { 1027 return src.Entity{}, &compiler.Error{ 1028 Err: err, 1029 Meta: &meta, 1030 } 1031 } 1032 parsedConst = src.Const{ 1033 Ref: &parsedRef, 1034 Meta: meta, 1035 } 1036 } else { 1037 parsedMsg, err := parseMessage(constVal) 1038 if err != nil { 1039 return src.Entity{}, &compiler.Error{ 1040 Err: err, 1041 Meta: &meta, 1042 } 1043 } 1044 typeExpr, err := parseTypeExpr(actx.TypeExpr()) 1045 if err != nil { 1046 return src.Entity{}, &compiler.Error{ 1047 Err: err, 1048 Meta: &meta, 1049 } 1050 } 1051 parsedMsg.TypeExpr = typeExpr 1052 parsedConst = src.Const{ 1053 Message: &parsedMsg, 1054 Meta: meta, 1055 } 1056 } 1057 1058 return src.Entity{ 1059 Kind: src.ConstEntity, 1060 Const: parsedConst, 1061 }, nil 1062 } 1063 1064 func parseCompDef(actx generated.ICompDefContext) (src.Entity, *compiler.Error) { 1065 parsedInterfaceDef, err := parseInterfaceDef(actx.InterfaceDef()) 1066 if err != nil { 1067 return src.Entity{}, err 1068 } 1069 1070 body := actx.CompBody() 1071 if body == nil { 1072 return src.Entity{ 1073 Kind: src.ComponentEntity, 1074 Component: src.Component{ 1075 Interface: parsedInterfaceDef, 1076 }, 1077 }, nil 1078 } 1079 1080 parsedConnections := []src.Connection{} 1081 connections := actx.CompBody().ConnDefList() 1082 if connections != nil { 1083 parsedNet, err := parseNet(connections) 1084 if err != nil { 1085 return src.Entity{}, err 1086 } 1087 parsedConnections = parsedNet 1088 } 1089 1090 nodesDef := body.CompNodesDef() 1091 if nodesDef == nil { 1092 return src.Entity{ 1093 Kind: src.ComponentEntity, 1094 Component: src.Component{ 1095 Interface: parsedInterfaceDef, 1096 Net: parsedConnections, 1097 }, 1098 }, nil 1099 } 1100 1101 var parsedNodes map[string]src.Node 1102 v, err := parseNodes(nodesDef.CompNodesDefBody(), true) 1103 if err != nil { 1104 return src.Entity{}, err 1105 } 1106 parsedNodes = v 1107 1108 return src.Entity{ 1109 Kind: src.ComponentEntity, 1110 Component: src.Component{ 1111 Interface: parsedInterfaceDef, 1112 Nodes: parsedNodes, 1113 Net: parsedConnections, 1114 }, 1115 }, nil 1116 }