def LoopParser(input): from smnp.ast.node.identifier import IdentifierLiteralParser from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.statement import StatementParser loopParameters = Parser.allOf( Parser.terminal(TokenType.AS), Parser.oneOf( Parser.wrap(IdentifierLiteralParser, lambda id: LoopParameters.withChildren([id], id.pos)), abstractIterableParser(LoopParameters, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, IdentifierLiteralParser)), createNode=lambda asKeyword, parameters: parameters, name="loop parameters") loopFilter = Parser.allOf(Parser.terminal(TokenType.PERCENT), Parser.doAssert(ExpressionWithoutLoopParser, "filter as bool expression"), createNode=lambda percent, expr: expr, name="loop filter") return Parser.allOf(ExpressionWithoutLoopParser, Parser.optional(loopParameters), Parser.terminal(TokenType.CARET, createNode=Operator.withValue), StatementParser, Parser.optional(loopFilter), createNode=Loop.loop, name="caret-loop")(input)
def ReturnParser(input): return Parser.allOf( Parser.terminal(TokenType.RETURN), Parser.optional(ExpressionParser), createNode=lambda ret, val: Return.withValue(val, ret.pos), name="return" )(input)
def RegularArgumentParser(input): def createNode(type, variable, vararg): pos = type.pos if isinstance(type, Type) else variable.pos node = Argument(pos) node.type = type node.variable = variable node.vararg = vararg is True return node return Parser.allOf(Parser.optional(TypeParser), Parser.doAssert(IdentifierLiteralParser, "argument name"), Parser.optional( Parser.terminal(TokenType.DOTS, lambda val, pos: True)), createNode=createNode, name="regular function argument")(input)
def withSemicolon(parser, optional=False, doAssert=False): semicolonParser = Parser.optional(Parser.terminal(TokenType.SEMICOLON)) if optional else Parser.terminal( TokenType.SEMICOLON, doAssert=doAssert) return Parser.allOf( parser, semicolonParser, createNode=lambda stmt, semicolon: stmt, name="semicolon" + "?" if optional else "" )
def OptionalArgumentParser(input): def createNode(type, variable, _, optional): pos = type.pos if isinstance(type, Type) else variable.pos node = Argument(pos) node.type = type node.variable = variable node.optionalValue = optional return node return Parser.allOf(Parser.optional(TypeParser), Parser.doAssert(IdentifierLiteralParser, "argument name"), Parser.terminal(TokenType.ASSIGN), Parser.doAssert(ExpressionParser, "expression"), createNode=createNode, name="optional function argument")(input)