Files
boring-lang/boring/parse.py

221 lines
5.1 KiB
Python
Raw Normal View History

2021-02-20 19:58:56 -07:00
import sys
import enum
2021-04-18 08:51:21 -06:00
from typing import Union, List
2021-02-20 19:58:56 -07:00
from dataclasses import dataclass, field
from lark import Lark, Transformer
2021-04-18 08:51:21 -06:00
def pretty_print(clas, indent=0):
print(' ' * indent + type(clas).__name__ + ':')
indent += 2
for k,v in clas.__dict__.items():
if '__dict__' in dir(v):
print(' ' * indent + k + ': ')
pretty_print(v,indent+2)
elif type(v) == list:
print(' ' * indent + k + ': ' "[")
for e in v:
pretty_print(e, indent+2)
print(' ' * indent + "]")
else:
print(' ' * indent + k + ': ' + str(v))
2021-02-20 19:58:56 -07:00
@dataclass
class Identifier:
name: str
class Operator(enum.Enum):
mult = "mult"
div = "div"
plus = "plus"
minus = "minus"
@dataclass
class LiteralInt:
value: int
@dataclass
class FunctionCall:
name: Identifier
2021-04-18 08:51:21 -06:00
arguments: List['Expression'] = field(default_factory=list)
2021-02-20 19:58:56 -07:00
@dataclass
class Operation:
left: 'Expression'
op: Operator
right: 'Expression'
@dataclass
class Expression:
expression: Union[LiteralInt,FunctionCall,Identifier,Operation,'Expression']
@dataclass
2021-04-18 08:51:21 -06:00
class LetStatement:
variable_name: Identifier
2021-02-20 19:58:56 -07:00
expression: Expression
2021-04-18 08:51:21 -06:00
@dataclass
class Statement:
statement: Union[LetStatement, Expression]
@dataclass
class Block:
statements: List[Statement]
2021-02-20 19:58:56 -07:00
@dataclass
class VariableDeclaration:
name: Identifier
@dataclass
class Function:
name: Identifier
2021-04-18 08:51:21 -06:00
arguments: List[VariableDeclaration]
2021-02-20 19:58:56 -07:00
block: Block
@dataclass
class Module:
functions: Function
boring_grammar = r"""
plus : "+"
minus : "-"
mult : "*"
div : "/"
literal_int: SIGNED_NUMBER
identifier : NAME
function_call : identifier "(" [expression ("," expression)*] ")"
add_expression : expression plus factor
sub_expression : expression minus factor
mult_expression : expression mult term
div_expression : expression div term
expression : add_expression
| sub_expression
| factor
factor : mult_expression
| div_expression
| term
term : literal_int
| identifier
| function_call
| "(" expression ")"
2021-04-18 08:51:21 -06:00
let_statement : "let" identifier "=" expression ";"
statement : let_statement
| expression
block : "{" (statement)* "}"
2021-02-20 19:58:56 -07:00
variable_declaration : identifier
function : "fn" identifier "(" [variable_declaration ("," variable_declaration)*] ")" block
module : (function)*
%import common.CNAME -> NAME
%import common.SIGNED_NUMBER
%import common.WS
%ignore WS
"""
class TreeToBoring(Transformer):
2021-04-18 08:51:21 -06:00
def plus(self, p) -> Operator:
2021-02-20 19:58:56 -07:00
return Operator.plus
2021-04-18 08:51:21 -06:00
def minus(self, m) -> Operator:
2021-02-20 19:58:56 -07:00
return Operator.minus
2021-04-18 08:51:21 -06:00
def mult(self, m) -> Operator:
2021-02-20 19:58:56 -07:00
return Operator.mult
2021-04-18 08:51:21 -06:00
def div(self, d) -> Operator:
2021-02-20 19:58:56 -07:00
return Operator.div
2021-04-18 08:51:21 -06:00
def literal_int(self, n) -> LiteralInt:
2021-02-20 19:58:56 -07:00
(n,) = n
return LiteralInt(value=int(n))
2021-04-18 08:51:21 -06:00
def identifier(self, i) -> Identifier:
2021-02-20 19:58:56 -07:00
(i,) = i
return Identifier(name=str(i))
2021-04-18 08:51:21 -06:00
def function_call(self, call) -> FunctionCall:
2021-02-20 19:58:56 -07:00
return FunctionCall(name=call[0], arguments=call[1:])
2021-04-18 08:51:21 -06:00
def add_expression(self, ae) -> Operation:
2021-02-20 19:58:56 -07:00
return Operation(left=ae[0], op=ae[1], right=ae[2])
2021-04-18 08:51:21 -06:00
def sub_expression(self, se) -> Operation:
2021-02-20 19:58:56 -07:00
return Operation(left=se[0], op=se[1], right=se[2])
2021-04-18 08:51:21 -06:00
def mult_expression(self, se) -> Operation:
2021-02-20 19:58:56 -07:00
return Operation(left=se[0], op=se[1], right=se[2])
2021-04-18 08:51:21 -06:00
def div_expression(self, se) -> Operation:
2021-02-20 19:58:56 -07:00
return Operation(left=se[0], op=se[1], right=se[2])
2021-04-18 08:51:21 -06:00
def expression(self, exp) -> Expression:
2021-02-20 19:58:56 -07:00
(exp,) = exp
2021-04-18 08:56:45 -06:00
if isinstance(exp, Expression):
2021-04-18 08:51:21 -06:00
return exp
2021-02-20 19:58:56 -07:00
return Expression(expression=exp)
2021-04-18 08:51:21 -06:00
def factor(self, factor) -> Expression:
2021-02-20 19:58:56 -07:00
(factor,) = factor
2021-04-18 08:56:45 -06:00
if isinstance(factor, Expression):
2021-04-18 08:51:21 -06:00
return factor
2021-02-20 19:58:56 -07:00
return Expression(factor)
2021-04-18 08:51:21 -06:00
def term(self, term) -> Expression:
2021-02-20 19:58:56 -07:00
(term,) = term
return Expression(term)
2021-04-18 08:51:21 -06:00
def let_statement(self, let_statement) -> LetStatement:
(variable_name, expression) = let_statement
return LetStatement(variable_name=variable_name, expression=expression)
def statement(self, statement) -> Statement:
(statement,) = statement
return Statement(statement=statement)
def block(self, block) -> Block:
return Block(statements=block)
2021-02-20 19:58:56 -07:00
2021-04-18 08:51:21 -06:00
def variable_declaration(self, identifier) -> VariableDeclaration:
2021-02-20 19:58:56 -07:00
(identifier,) = identifier
return VariableDeclaration(name=identifier)
2021-04-18 08:51:21 -06:00
def function(self, function) -> Function:
2021-02-20 19:58:56 -07:00
return Function(name=function[0], arguments=function[1:-1], block=function[-1])
2021-04-18 08:51:21 -06:00
def module(self, functions) -> Module:
2021-02-20 19:58:56 -07:00
return Module(functions=functions)
boring_parser = Lark(boring_grammar, start='module', lexer='standard')
if __name__ == '__main__':
with open(sys.argv[1]) as f:
tree = boring_parser.parse(f.read())
2021-04-18 08:51:21 -06:00
# print(tree)
result = TreeToBoring().transform(tree)
pretty_print(result)