| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 
 | -- Some test code that tries to simulate important/interesting parts of mypy itself!
[case testSimulateMypy]
from mypy_extensions import trait
from typing import List, TypeVar, cast, Generic
from abc import abstractmethod
import other_strconv as strconv
#from other_visitor import ExpressionVisitor, StatementVisitor, NodeVisitor
import other_visitor as visitor
T = TypeVar('T')
############ nodes.py
class Context:
    def __init__(self) -> None:
        self.line = -1
    def set_line(self, line: int) -> None:
        self.line = line
class Node(Context):
    def accept(self, visitor: visitor.NodeVisitor[T]) -> T: return cast(T, None)
    def to_str(self) -> str:
        return self.accept(strconv.StrConv())
@trait
class Statement(Node):
    def accept(self, visitor: visitor.StatementVisitor[T]) -> T: return cast(T, None)
@trait
class Expression(Node):
    def accept(self, visitor: visitor.ExpressionVisitor[T]) -> T: return cast(T, None)
@trait
class SymbolNode(Node):
    """Nodes that can be stored in a symbol table."""
    @abstractmethod
    def name(self) -> str: return cast(str, None)
class FuncBase(Node):
    def __init__(self) -> None:
        super().__init__()
        self.is_static = False
class Block(Statement):
    def __init__(self, stmts: List[Statement]) -> None:
        self.stmts = stmts
    def accept(self, visitor: visitor.StatementVisitor[T]) -> T:
        return visitor.visit_block(self)
class ExprStmt(Statement):
    def __init__(self, expr: Expression) -> None:
        self.expr = expr
    def accept(self, visitor: visitor.StatementVisitor[T]) -> T:
        return visitor.visit_expr_stmt(self)
class FuncItem(FuncBase):
    def __init__(self, body: Block) -> None:
        self.body = body
class FuncDef(FuncItem, SymbolNode, Statement):
    def __init__(self, name: str, body: Block) -> None:
        super().__init__(body)
        self._name = name
    def accept(self, visitor: visitor.StatementVisitor[T]) -> T:
        return visitor.visit_func_def(self)
    def name(self) -> str:
        return self._name
class LambdaExpr(FuncItem, Expression):
    def accept(self, visitor: visitor.ExpressionVisitor[T]) -> T:
        return visitor.visit_lambda_expr(self)
def lol(x: Statement) -> int:
    return x.line
[file other_visitor.py]
from mypy_extensions import trait
from typing import TypeVar, cast, Generic
from abc import abstractmethod
import native as nodes
T = TypeVar('T')
@trait
class ExpressionVisitor(Generic[T]):
    @abstractmethod
    def visit_lambda_expr(self, o: 'nodes.LambdaExpr') -> T:
        return cast(T, None)
@trait
class StatementVisitor(Generic[T]):
    @abstractmethod
    def visit_block(self, o: 'nodes.Block') -> T:
        return cast(T, None)
    @abstractmethod
    def visit_func_def(self, o: 'nodes.FuncDef') -> T:
        return cast(T, None)
    @abstractmethod
    def visit_expr_stmt(self, o: 'nodes.ExprStmt') -> T:
        return cast(T, None)
@trait
class NodeVisitor(Generic[T], ExpressionVisitor[T], StatementVisitor[T]):
    pass
[file other_strconv.py]
from typing import List
import native as nodes
from other_visitor import NodeVisitor
class StrConv(NodeVisitor[str]):
    def visit_block(self, b: nodes.Block) -> str:
        # we really need comprehensions!
        # TODO: PartialType unsupported
        things = []  # type: List[str]
        for s in b.stmts:
            things.append(s.accept(self))
        return "{" + "; ".join(things) + "}"
    def visit_func_def(self, f: nodes.FuncDef) -> str:
        return "def " + f.name() + "(): " + f.body.accept(self)
    def visit_expr_stmt(self, e: nodes.ExprStmt) -> str:
        return e.expr.accept(self)
    def visit_lambda_expr(self, b: nodes.LambdaExpr) -> str:
        return "(fn: " + b.body.accept(self) + ")"
[file driver.py]
from native import *
block = Block([Block([]), ExprStmt(LambdaExpr(Block([])))])
fn = FuncDef('test', block)
assert fn.to_str() == "def test(): {{}; (fn: {})}"
 |