From 3e506354cd73297614c898376c0124e9818f5a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Thu, 11 Jul 2019 10:23:28 +0200 Subject: [PATCH] Add imports statements --- smnp/ast/node/atom.py | 46 ++++++++---- smnp/ast/node/imports.py | 145 +++++++++++++++++++++++-------------- smnp/ast/node/program.py | 2 + smnp/ast/node/statement.py | 2 +- 4 files changed, 125 insertions(+), 70 deletions(-) diff --git a/smnp/ast/node/atom.py b/smnp/ast/node/atom.py index 49d09e2..b1cfb6d 100644 --- a/smnp/ast/node/atom.py +++ b/smnp/ast/node/atom.py @@ -43,32 +43,52 @@ class TypeLiteral(Atom): pass -def LiteralParser(input): - integerParser = Parser.oneOf( +def IntegerParser(input): + return Parser.oneOf( Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)), Parser.allOf( Parser.terminalParser(TokenType.MINUS), Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)), - createNode=lambda minus, integer: IntegerLiteral.withValue(-integer.value, minus.pos) + createNode=lambda minus, integer: IntegerLiteral.withValue(-integer.value, minus.pos), + name="negative integer" ) - ) + )(input) + +def StringParser(input): + return Parser.terminalParser(TokenType.STRING, createNode=StringLiteral.withValue)(input) + + +def NoteParser(input): + return Parser.terminalParser(TokenType.NOTE, createNode=NoteLiteral.withValue)(input) + + +def BoolParser(input): + return Parser.terminalParser(TokenType.BOOL, createNode=BoolLiteral.withValue)(input) + + +def TypeParser(input): + return Parser.terminalParser(TokenType.TYPE, createNode=TypeLiteral.withValue)(input) + + +def LiteralParser(input): return Parser.oneOf( - integerParser, - Parser.terminalParser(TokenType.STRING, createNode=StringLiteral.withValue), - Parser.terminalParser(TokenType.NOTE, createNode=NoteLiteral.withValue), - Parser.terminalParser(TokenType.BOOL, createNode=BoolLiteral.withValue), - Parser.terminalParser(TokenType.TYPE, createNode=TypeLiteral.withValue), + IntegerParser, + StringParser, + NoteParser, + BoolParser, + TypeParser, + name="literal" )(input) def AtomParser(input): from smnp.ast.node.identifier import IdentifierParser - - parser = Parser.oneOf( + return Parser.oneOf( LiteralParser, IdentifierParser, - ) + name="atom" + )(input) + - return Parser(parser, "atom", parser)(input) diff --git a/smnp/ast/node/imports.py b/smnp/ast/node/imports.py index d648620..43a30be 100644 --- a/smnp/ast/node/imports.py +++ b/smnp/ast/node/imports.py @@ -1,16 +1,21 @@ -from smnp.ast.node.identifier import Identifier +# from smnp.ast.node.identifier import Identifier +# from smnp.ast.node.model import Node +# from smnp.ast.node.none import NoneNode +# from smnp.ast.node.string import StringLiteralNode +# from smnp.ast.node.type import TypeNode +# from smnp.ast.parser import Parser +# from smnp.token.type import TokenType +# +from smnp.ast.node.atom import StringParser from smnp.ast.node.model import Node -from smnp.ast.node.none import NoneNode -from smnp.ast.node.string import StringLiteralNode -from smnp.ast.node.type import TypeNode from smnp.ast.parser import Parser from smnp.token.type import TokenType -class ImportNode(Node): +class Import(Node): def __init__(self, pos): super().__init__(pos) - self.children = [NoneNode(), NoneNode(), NoneNode()] + self.children = [None] @property def source(self): @@ -20,57 +25,85 @@ class ImportNode(Node): def source(self, value): self[0] = value - @property - def type(self): - return self[1] - - @type.setter - def type(self, value): - self[1] = value - - @property - def variable(self): - return self[2] - - @variable.setter - def variable(self, value): - self[2] = value - @classmethod - def _parse(cls, input): - return Parser.oneOf( - cls._literalImportParser(), - cls._fileImportParser() - )(input) + def withValue(cls, value): + node = cls(value.pos) + node.source = value + return node - @classmethod - def _literalImportParser(cls): - def createNode(importKeyword, type, fromKeyword, source, asKeyword, variable): - node = ImportNode(importKeyword.pos) - node.source = source - node.type = type - node.variable = variable - return node - return Parser.allOf( - Parser.terminalParser(TokenType.IMPORT), - TypeNode.parse, - Parser.doAssert(Parser.terminalParser(TokenType.FROM), "'from as '"), - Parser.doAssert(StringLiteralNode._literalParser(), "source as a string"), - Parser.doAssert(Parser.terminalParser(TokenType.AS), "'as '"), - Parser.doAssert(Identifier.identifierParser(), "variable name"), - createNode=createNode - ) +def ImportParser(input): + return Parser.allOf( + Parser.terminalParser(TokenType.IMPORT), + StringParser, + createNode=lambda imp, source: Import.withValue(source), + name="import" + )(input) - @classmethod - def _fileImportParser(cls): - def createNode(importKeyword, source): - node = ImportNode(importKeyword.pos) - node.source = source - return node - - return Parser.allOf( - Parser.terminalParser(TokenType.IMPORT), - Parser.doAssert(StringLiteralNode._literalParser(), "source as a string"), - createNode=createNode - ) +# class ImportNode(Node): +# def __init__(self, pos): +# super().__init__(pos) +# self.children = [NoneNode(), NoneNode(), NoneNode()] +# +# @property +# def source(self): +# return self[0] +# +# @source.setter +# def source(self, value): +# self[0] = value +# +# @property +# def type(self): +# return self[1] +# +# @type.setter +# def type(self, value): +# self[1] = value +# +# @property +# def variable(self): +# return self[2] +# +# @variable.setter +# def variable(self, value): +# self[2] = value +# +# @classmethod +# def _parse(cls, input): +# return Parser.oneOf( +# cls._literalImportParser(), +# cls._fileImportParser() +# )(input) +# +# @classmethod +# def _literalImportParser(cls): +# def createNode(importKeyword, type, fromKeyword, source, asKeyword, variable): +# node = ImportNode(importKeyword.pos) +# node.source = source +# node.type = type +# node.variable = variable +# return node +# +# return Parser.allOf( +# Parser.terminalParser(TokenType.IMPORT), +# TypeNode.parse, +# Parser.doAssert(Parser.terminalParser(TokenType.FROM), "'from as '"), +# Parser.doAssert(StringLiteralNode._literalParser(), "source as a string"), +# Parser.doAssert(Parser.terminalParser(TokenType.AS), "'as '"), +# Parser.doAssert(Identifier.identifierParser(), "variable name"), +# createNode=createNode +# ) +# +# @classmethod +# def _fileImportParser(cls): +# def createNode(importKeyword, source): +# node = ImportNode(importKeyword.pos) +# node.source = source +# return node +# +# return Parser.allOf( +# Parser.terminalParser(TokenType.IMPORT), +# Parser.doAssert(StringLiteralNode._literalParser(), "source as a string"), +# createNode=createNode +# ) diff --git a/smnp/ast/node/program.py b/smnp/ast/node/program.py index 61024d0..28a3284 100644 --- a/smnp/ast/node/program.py +++ b/smnp/ast/node/program.py @@ -1,3 +1,4 @@ +from smnp.ast.node.imports import ImportParser from smnp.ast.node.model import Node, ParseResult from smnp.ast.node.statement import StatementParser from smnp.ast.parser import Parser @@ -12,6 +13,7 @@ def parse(input): while input.hasCurrent(): result = Parser.oneOf( # Start Symbol + ImportParser, StatementParser, exception=RuntimeError("Nie znam tego wyrazenia") )(input) diff --git a/smnp/ast/node/statement.py b/smnp/ast/node/statement.py index d8f37fe..6b0cc0b 100644 --- a/smnp/ast/node/statement.py +++ b/smnp/ast/node/statement.py @@ -9,8 +9,8 @@ class Statement(Node): def StatementParser(input): from smnp.ast.node.block import BlockParser - from smnp.ast.node.condition import IfElseStatementParser + parser = Parser.oneOf( IfElseStatementParser, BlockParser,