Enable parser to handle optional arguments

This commit is contained in:
Bartłomiej Pluta
2019-07-13 23:08:35 +02:00
parent e70b5fa71a
commit 6bd8046346
2 changed files with 39 additions and 3 deletions

View File

@@ -1,4 +1,5 @@
from smnp.ast.node.block import BlockParser from smnp.ast.node.block import BlockParser
from smnp.ast.node.expression import ExpressionParser
from smnp.ast.node.identifier import IdentifierLiteralParser from smnp.ast.node.identifier import IdentifierLiteralParser
from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.iterable import abstractIterableParser
from smnp.ast.node.model import Node from smnp.ast.node.model import Node
@@ -16,7 +17,7 @@ class Argument(Node):
def __init__(self, pos): def __init__(self, pos):
super().__init__(pos) super().__init__(pos)
self.children = [NoneNode(), NoneNode(), False] self.children = [NoneNode(), NoneNode(), False, NoneNode()]
@property @property
def type(self): def type(self):
@@ -48,6 +49,14 @@ class Argument(Node):
self[2] = value self[2] = value
@property
def optionalValue(self):
return self[3]
@optionalValue.setter
def optionalValue(self, value):
self[3] = value
class VarargNode(Node): class VarargNode(Node):
pass pass
@@ -90,7 +99,7 @@ class FunctionDefinition(Node):
return node return node
def ArgumentParser(input): def RegularArgumentParser(input):
def createNode(type, variable, vararg): def createNode(type, variable, vararg):
pos = type.pos if isinstance(type, Type) else variable.pos pos = type.pos if isinstance(type, Type) else variable.pos
node = Argument(pos) node = Argument(pos)
@@ -104,6 +113,33 @@ def ArgumentParser(input):
Parser.doAssert(IdentifierLiteralParser, "argument name"), Parser.doAssert(IdentifierLiteralParser, "argument name"),
Parser.optional(Parser.terminal(TokenType.DOTS, lambda val, pos: True)), Parser.optional(Parser.terminal(TokenType.DOTS, lambda val, pos: True)),
createNode=createNode, createNode=createNode,
name="regular function argument"
)(input)
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)
def ArgumentParser(input):
return Parser.oneOf(
OptionalArgumentParser,
RegularArgumentParser,
name="function argument" name="function argument"
)(input) )(input)

View File

@@ -8,7 +8,7 @@ from smnp.program.interpreter import Interpreter
def main(): def main():
try: try:
stdLibraryEnv = loadStandardLibrary() stdLibraryEnv = loadStandardLibrary()
Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=False, execute=True, baseEnvironment=stdLibraryEnv) Interpreter.interpretFile(sys.argv[1], printTokens=False, printAst=True, execute=True, baseEnvironment=stdLibraryEnv)
#draft() #draft()
#tokens = tokenize(['function a(b...) { x+y}']) #tokens = tokenize(['function a(b...) { x+y}'])
#FunctionDefinitionParser(tokens).node.print() #FunctionDefinitionParser(tokens).node.print()