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):
pass
def AtomParser(input):
from smnp.ast.node.identifier import IdentifierParser
class TypeLiteral(Atom):
pass
def LiteralParser(input):
integerParser = Parser.oneOf(
Parser.terminalParser(TokenType.INTEGER, lambda val, pos: IntegerLiteral.withValue(int(val), pos)),
Parser.allOf(
@@ -50,11 +53,25 @@ def AtomParser(input):
)
)
parser = Parser.oneOf(
return Parser.oneOf(
integerParser,
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)),
)(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,
)

View File

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

View File

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