Enable support for custom functions definition

This commit is contained in:
Bartłomiej Pluta
2019-07-12 00:13:20 +02:00
parent af3cb7027a
commit eb28976704
4 changed files with 143 additions and 137 deletions

View File

@@ -1,128 +1,127 @@
# from smnp.ast.node.block import BlockNode from smnp.ast.node.block import BlockParser
# from smnp.ast.node.expression import ExpressionNode from smnp.ast.node.identifier import IdentifierLiteralParser
# from smnp.ast.node.identifier import IdentifierNode 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 from smnp.ast.node.none import NoneNode
# from smnp.ast.node.none import NoneNode from smnp.ast.node.type import TypeParser, Type
# from smnp.ast.node.statement import StatementNode from smnp.ast.parser import Parser
# from smnp.ast.node.type import TypeNode, TypeSpecifier from smnp.token.type import TokenType
# from smnp.ast.parser import Parser
# from smnp.token.type import TokenType
# class ArgumentsDeclaration(Node):
# pass
# class ArgumentsDeclarationNode(Node):
#
# @classmethod class Argument(Node):
# def _parse(cls, input):
# raise RuntimeError("This class is not supposed to be automatically called") def __init__(self, pos):
# super().__init__(pos)
# self.children = [NoneNode(), NoneNode(), False]
# class VarargNode(Node):
# pass @property
# def type(self):
# return self[0]
# class ArgumentDefinitionNode(ExpressionNode):
# def __init__(self, pos):
# super().__init__(pos) @type.setter
# self.children.extend([NoneNode(), False]) def type(self, value):
# self[0] = value
# @property
# def type(self):
# return self[0] @property
# def variable(self):
# @type.setter return self[1]
# def type(self, value):
# self[0] = value
# @variable.setter
# @property def variable(self, value):
# def variable(self): self[1] = value
# return self[1]
#
# @variable.setter @property
# def variable(self, value): def vararg(self):
# self[1] = value return self[2]
#
# @property
# def vararg(self): @vararg.setter
# return self[2] def vararg(self, value):
# self[2] = value
# @vararg.setter
# def vararg(self, value):
# self[2] = value class VarargNode(Node):
# pass
#
# @classmethod
# def parser(cls): class FunctionDefinition(Node):
# def createNode(type, variable, dots): def __init__(self, pos):
# node = ArgumentDefinitionNode(type.pos) super().__init__(pos)
# node.type = type self.children = [NoneNode(), NoneNode(), NoneNode()]
# node.variable = variable
# node.vararg = isinstance(dots, VarargNode) @property
# return node def name(self):
# return self[0]
# return Parser.allOf(
# Parser.optional(Parser.oneOf( @name.setter
# TypeNode.parse, def name(self, value):
# TypeSpecifier.parse self[0] = value
# )),
# Parser.doAssert(IdentifierNode.identifierParser(), "variable name"), @property
# Parser.optional(Parser.terminalParser(TokenType.DOTS, lambda val, pos: VarargNode(pos))), def arguments(self):
# createNode=createNode return self[1]
# )
# @arguments.setter
# @classmethod def arguments(self, value):
# def _parse(cls, input): self[1] = value
# #TODO
# raise RuntimeError("Not implemented yet. There is still required work to correctly build AST related to IdentifierNode") @property
# def body(self):
# return self[2]
#
# class FunctionDefinitionNode(StatementNode): @body.setter
# def __init__(self, pos): def body(self, value):
# super().__init__(pos) self[2] = value
# self.children = [NoneNode(), NoneNode(), NoneNode()]
# @classmethod
# @property def withValues(cls, name, arguments, body):
# def name(self): node = cls(name.pos)
# return self[0] node.name = name
# node.arguments = arguments
# @name.setter node.body = body
# def name(self, value): return node
# self[0] = value
#
# @property def ArgumentParser(input):
# def arguments(self): def createNode(type, variable, vararg):
# return self[1] pos = type.pos if isinstance(type, Type) else variable.pos
# node = Argument(pos)
# @arguments.setter node.type = type
# def arguments(self, value): node.variable = variable
# self[1] = value node.vararg = vararg is True
# return node
# @property
# def body(self): return Parser.allOf(
# return self[2] Parser.optional(TypeParser),
# IdentifierLiteralParser,
# @body.setter Parser.optional(Parser.terminalParser(TokenType.DOTS, lambda val, pos: True)),
# def body(self, value): createNode=createNode,
# self[2] = value name="function argument"
# )(input)
# @classmethod
# def _parse(cls, input):
# def createNode(function, name, arguments, body): def ArgumentsDeclarationParser(input):
# node = FunctionDefinitionNode(function.pos) return abstractIterableParser(
# node.name = name ArgumentsDeclaration,
# node.arguments = arguments TokenType.OPEN_PAREN,
# node.body = body TokenType.CLOSE_PAREN,
# return node ArgumentParser
# )(input)
# return Parser.allOf(
# Parser.terminalParser(TokenType.FUNCTION),
# Parser.doAssert(IdentifierNode.identifierParser(), "function name"), def FunctionDefinitionParser(input):
# Parser.doAssert(cls._argumentsDeclarationParser(), "arguments list"), return Parser.allOf(
# Parser.doAssert(BlockNode.parse, "function body"), Parser.terminalParser(TokenType.FUNCTION),
# createNode=createNode IdentifierLiteralParser,
# )(input) ArgumentsDeclarationParser,
# BlockParser,
# @staticmethod createNode=lambda _, name, args, body: FunctionDefinition.withValues(name, args, body)
# def _argumentsDeclarationParser(): )(input)
# return abstractIterableParser(ArgumentsDeclarationNode, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, ArgumentDefinitionNode.parser())

View File

@@ -49,17 +49,21 @@ class Assignment(BinaryOperator):
pass pass
def IdentifierLiteralParser(input):
return Parser.terminalParser(TokenType.IDENTIFIER, createNode=Identifier.withValue)(input)
def IdentifierParser(input): def IdentifierParser(input):
identifierLiteralParser = Parser.terminalParser(TokenType.IDENTIFIER, createNode=Identifier.withValue)
functionCallParser = Parser.allOf( functionCallParser = Parser.allOf(
identifierLiteralParser, IdentifierLiteralParser,
abstractIterableParser(ArgumentsList, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, ExpressionParser), abstractIterableParser(ArgumentsList, TokenType.OPEN_PAREN, TokenType.CLOSE_PAREN, ExpressionParser),
createNode=lambda name, arguments: FunctionCall.withChildren(name, arguments) createNode=lambda name, arguments: FunctionCall.withChildren(name, arguments)
) )
assignmentParser = Parser.allOf( assignmentParser = Parser.allOf(
identifierLiteralParser, IdentifierLiteralParser,
Parser.terminalParser(TokenType.ASSIGN, createNode=Operator.withValue), Parser.terminalParser(TokenType.ASSIGN, createNode=Operator.withValue),
ExpressionParser, ExpressionParser,
createNode=lambda identifier, assign, expr: Assignment.withValues(identifier, assign, expr) createNode=lambda identifier, assign, expr: Assignment.withValues(identifier, assign, expr)
@@ -68,5 +72,5 @@ def IdentifierParser(input):
return Parser.oneOf( return Parser.oneOf(
assignmentParser, assignmentParser,
functionCallParser, functionCallParser,
identifierLiteralParser IdentifierLiteralParser
)(input) )(input)

View File

@@ -1,3 +1,4 @@
from smnp.ast.node.function import FunctionDefinitionParser
from smnp.ast.node.imports import ImportParser from smnp.ast.node.imports import ImportParser
from smnp.ast.node.model import Node, ParseResult from smnp.ast.node.model import Node, ParseResult
from smnp.ast.node.statement import StatementParser from smnp.ast.node.statement import StatementParser
@@ -15,6 +16,7 @@ def ProgramParser(input):
result = Parser.oneOf( result = Parser.oneOf(
# Start Symbol # Start Symbol
ImportParser, ImportParser,
FunctionDefinitionParser,
StatementParser, StatementParser,
exception=RuntimeError("Nie znam tego wyrazenia") exception=RuntimeError("Nie znam tego wyrazenia")
)(input) )(input)

View File

@@ -1,15 +1,16 @@
from smnp.ast.node.type import TypeParser import sys
from smnp.error.base import SmnpException from smnp.error.base import SmnpException
from smnp.token.tokenizer import tokenize from smnp.program.interpreter import Interpreter
def main(): def main():
try: try:
#stdLibraryEnv = loadStandardLibrary() #stdLibraryEnv = loadStandardLibrary()
#Interpreter.interpretFile(sys.argv[1], printTokens=True, printAst=True, execute=False, baseEnvironment=None) Interpreter.interpretFile(sys.argv[1], printTokens=True, printAst=True, execute=False, baseEnvironment=None)
#draft() #draft()
tokens = tokenize(['<list, string>']) #tokens = tokenize(['function a(b...) { x+y}'])
TypeParser(tokens).node.print() #FunctionDefinitionParser(tokens).node.print()
except SmnpException as e: except SmnpException as e:
print(e.message()) print(e.message())