Add optional 'as' operator to loop

This commit is contained in:
Bartłomiej Pluta
2019-07-12 14:12:55 +02:00
parent 0cefcd282b
commit b7192ea52b
2 changed files with 50 additions and 1 deletions

View File

@@ -1,4 +1,7 @@
from smnp.ast.node.chain import ChainParser from smnp.ast.node.chain import ChainParser
from smnp.ast.node.iterable import abstractIterableParser
from smnp.ast.node.model import Node
from smnp.ast.node.none import NoneNode
from smnp.ast.node.operator import BinaryOperator, Operator, UnaryOperator from smnp.ast.node.operator import BinaryOperator, Operator, UnaryOperator
from smnp.ast.node.valuable import Valuable from smnp.ast.node.valuable import Valuable
from smnp.ast.parser import Parser from smnp.ast.parser import Parser
@@ -14,12 +17,36 @@ class NotOperator(UnaryOperator):
class Loop(BinaryOperator): class Loop(BinaryOperator):
def __init__(self, pos):
super().__init__(pos)
self.children.append(NoneNode())
@property
def parameters(self):
return self[3]
@parameters.setter
def parameters(self, value):
self[3] = value
@classmethod
def loop(cls, left, parameters, operator, right):
node = cls(left.pos)
node.left = left
node.parameters = parameters
node.operator = operator
node.right = right
return node
class LoopParameters(Node):
pass pass
def FactorParser(input): def FactorParser(input):
from smnp.ast.node.expression import ExpressionParser from smnp.ast.node.expression import ExpressionParser
from smnp.ast.node.statement import StatementParser from smnp.ast.node.statement import StatementParser
from smnp.ast.node.identifier import IdentifierLiteralParser
powerFactor = Parser.leftAssociativeOperatorParser( powerFactor = Parser.leftAssociativeOperatorParser(
ChainParser, ChainParser,
@@ -50,11 +77,22 @@ def FactorParser(input):
name="not" name="not"
) )
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"
)
loopFactor = Parser.allOf( loopFactor = Parser.allOf(
factorParser, factorParser,
Parser.optional(loopParameters),
Parser.terminal(TokenType.DASH, createNode=Operator.withValue), Parser.terminal(TokenType.DASH, createNode=Operator.withValue),
StatementParser, StatementParser,
createNode=Loop.withValues, createNode=Loop.loop,
name="dash-loop" name="dash-loop"
) )

View File

@@ -207,3 +207,14 @@ class Parser:
return ParseResult.OK(createNode(results, pos) if len(results) > 0 else NoneNode()) return ParseResult.OK(createNode(results, pos) if len(results) > 0 else NoneNode())
return Parser(parse, name, parsers=[parser]) return Parser(parse, name, parsers=[parser])
@staticmethod
def wrap(parser, createNode):
def parse(input):
result = parser(input)
if result.result:
return ParseResult.OK(createNode(result.node))
return result
return parse