private AST Selector() { AST blockAST = Block(); if (currentToken.Type == TokenType.COLON) { Eat(TokenType.COLON); PortAST portAST = Port(); blockAST = new SelectAST(blockAST, portAST); } return(blockAST); }
private ILinkable Visit(SelectAST selectAST) { ILinkable linkable = Visit(selectAST.ModelObject) as ILinkable; if (linkable != null) { string portId = Visit(selectAST.Port.PortId); try { Port port = linkable.Expose(portId); switch (port) { case InPort inPort: return(inPort); case OutPort outPort: string signalName = selectAST.Port.PortName == null? null : Visit(selectAST.Port.PortName); if (signalName != null) { Node node = ModelManager.Create("Node") as Node; outPort.SignalName = signalName; node.Name = outPort.SignalName; outPort.Bind(node.Expose(0)); TypeSymbol typeSymbol = currentScope.Lookup("Node") as TypeSymbol; ModelSymbol modelSymbol = new ModelSymbol(signalName, typeSymbol, node); if (!currentScope.Insert(modelSymbol, false)) { throw logger.Error(new SemanticException(selectAST.Port.PortName.ReferenceToken, $"Duplicated ID {signalName}")); } } Group group = new Group(); group.AddInputModel(linkable); group.AddOutputModel(outPort); return(group); default: throw logger.Error(new SemanticException(selectAST.Port.FindToken(), "Ambiguous port")); } } catch (LigralException) { throw logger.Error(new SemanticException(selectAST.Port.FindToken())); } } else { throw logger.Error(new SemanticException(selectAST.ModelObject.FindToken(), "Non model object")); } }