Add support for maps

This commit is contained in:
Bartłomiej Pluta
2019-07-11 00:08:12 +02:00
parent 10c701ecbf
commit 3bbacad83b
3 changed files with 44 additions and 43 deletions

View File

@@ -38,9 +38,12 @@ class NoteLiteral(Atom):
class BoolLiteral(Atom): class BoolLiteral(Atom):
pass pass
def AtomParser(input):
from smnp.ast.node.identifier import IdentifierParser
class TypeLiteral(Atom):
pass
def LiteralParser(input):
integerParser = Parser.oneOf( integerParser = Parser.oneOf(
Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)), Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)),
Parser.allOf( Parser.allOf(
@@ -50,11 +53,25 @@ def AtomParser(input):
) )
) )
parser = Parser.oneOf( return Parser.oneOf(
integerParser, integerParser,
Parser.terminalParser(TokenType.STRING, lambda val, pos: StringLiteral.withValue(val, pos)), Parser.terminalParser(TokenType.STRING, lambda val, pos: StringLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.NOTE, lambda val, pos: NoteLiteral.withValue(val, pos)), Parser.terminalParser(TokenType.NOTE, lambda val, pos: NoteLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.BOOL, lambda val, pos: BoolLiteral.withValue(val, pos)), Parser.terminalParser(TokenType.BOOL, lambda val, pos: BoolLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.TYPE, lambda val, pos: TypeLiteral.withValue(val, pos)),
)(input)
def AtomParser(input):
from smnp.ast.node.identifier import IdentifierParser
parser = Parser.oneOf(
LiteralParser,
Parser.terminalParser(TokenType.STRING, lambda val, pos: StringLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.NOTE, lambda val, pos: NoteLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.BOOL, lambda val, pos: BoolLiteral.withValue(val, pos)),
Parser.terminalParser(TokenType.TYPE, lambda val, pos: TypeLiteral.withValue(val, pos)),
IdentifierParser, IdentifierParser,
) )

View File

@@ -1,5 +1,6 @@
from smnp.ast.node.atom import AtomParser from smnp.ast.node.atom import AtomParser
from smnp.ast.node.list import ListParser from smnp.ast.node.list import ListParser
from smnp.ast.node.map import MapParser
from smnp.ast.node.operator import BinaryOperator from smnp.ast.node.operator import BinaryOperator
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
@@ -11,6 +12,7 @@ class Chain(Valuable):
itemParser = Parser.oneOf( itemParser = Parser.oneOf(
ListParser, ListParser,
MapParser,
AtomParser, AtomParser,
) )

View File

@@ -1,20 +1,12 @@
from smnp.ast.node.bool import BoolLiteralNode from smnp.ast.node.atom import LiteralParser
from smnp.ast.node.expression import ExpressionNode
from smnp.ast.node.integer import IntegerLiteralNode
from smnp.ast.node.iterable import abstractIterableParser from smnp.ast.node.iterable import abstractIterableParser
from smnp.ast.node.none import NoneNode from smnp.ast.node.model import Node
from smnp.ast.node.note import NoteLiteralNode from smnp.ast.node.operator import BinaryOperator, Operator
from smnp.ast.node.operator import LeftAssociativeOperatorNode
from smnp.ast.node.string import StringLiteralNode
from smnp.ast.node.type import TypeNode
from smnp.ast.parser import Parser from smnp.ast.parser import Parser
from smnp.token.type import TokenType from smnp.token.type import TokenType
class MapEntry(ExpressionNode): class MapEntry(BinaryOperator):
def __init__(self, pos):
super().__init__(pos)
self.children = [NoneNode(), NoneNode()]
@property @property
def key(self): def key(self):
@@ -26,39 +18,29 @@ class MapEntry(ExpressionNode):
@property @property
def value(self): def value(self):
return self[1] return self[2]
@value.setter @value.setter
def value(self, value): def value(self, value):
self[1] = value self[2] = value
class MapNode(LeftAssociativeOperatorNode):
@classmethod class Map(Node):
def _lhsParser(cls): pass
return abstractIterableParser(MapNode, TokenType.OPEN_CURLY, TokenType.CLOSE_CURLY, cls._entryParser())
@classmethod
def _entryParser(cls):
def createNode(key, arrow, value):
node = MapEntry(key.pos)
node.key = key
node.value = value
return node
return Parser.allOf( def MapParser(input):
cls._keyParser(), from smnp.ast.node.expression import MaxPrecedenceExpressionParser
Parser.terminalParser(TokenType.ARROW), keyParser = LiteralParser
ExpressionNode.parse, valueParser = MaxPrecedenceExpressionParser
createNode=createNode
)
@classmethod mapEntryParser = Parser.allOf(
def _keyParser(cls): keyParser,
return Parser.oneOf( Parser.terminalParser(TokenType.ARROW, createNode=Operator.withValue),
IntegerLiteralNode.literalParser(), valueParser,
StringLiteralNode.literalParser(), createNode=MapEntry.withValues
NoteLiteralNode.literalParser(), )
BoolLiteralNode.literalParser(),
TypeNode.parse mapParser = abstractIterableParser(Map, TokenType.OPEN_CURLY, TokenType.CLOSE_CURLY, mapEntryParser)
)
return Parser(mapParser, "map", [mapParser])(input)