Enable support for custom functions definition
This commit is contained in:
@@ -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())
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
11
smnp/main.py
11
smnp/main.py
@@ -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())
|
||||||
|
|||||||
Reference in New Issue
Block a user