def resolve_arrow(arrow, args, scope=Scope(), depth=0): from kiwi.operations.replace import kreplace # builder.builtin('return', Arrow([make_var('T', 'Type')], Arrow([make_var('r', 'T')], ref('T')))) meta_args = {} if arrow.compile_time: meta = arrow arrow = arrow.return_type for meta_arg in meta.args: meta_args[meta_arg.name] = meta_arg.type for targ, varg in zip(arrow.args, args): v = type_trace(varg, scope, depth + 1, hint=targ.type) # print(varg, v) expr, type = v meta_args[targ.type.name] = type # /!\ Awful complexity arrow = kreplace(targ.type, type, arrow) else: for targ, varg in zip(arrow.args, args): expr, type = type_trace(varg, scope, depth + 1, hint=targ.type) assert ktype_equiv(type, targ.type, scope) return arrow
def __init__(self, ctx=Scope()): super(ToStringV).__init__() # enter a new scope to not affect the original scope self.env_stack: Scope = ctx.enter_scope(name='visitor_scope') self.bind_name = [] self._i = 0 self.line = 0 self.indent_size = 2 self.indent_char = ' '
def _make_default_scope() -> Scope: """ Make scope with default builtins the top level scope will always be the builtin scope The Builtin scope should be identical to all scopes """ ctx = Scope(name='root') builder = AstBuilder(ctx) builder.bind('Type', Builtin('Type', None)) def ref(name: str) -> Expression: return builder.reference(name) # Default high level types builder.bind('Expression', Builtin('Expression', ref('Type'))) builder.bind('Symbol', Builtin('Symbol', ref('Type'))) # Symbol, Type Pair builder.bind('Variable', Builtin('Variable', ref('Type'))) builder.bind('Float', Builtin('Float', ref('Type'))) builder.bind('Int', Builtin('Int', ref('Type'))) builder.bind('Bool', Builtin('Bool', ref('Type'))) def make_var(name, type): return builder.variable(name, ref(type)) # return T -> T builder.builtin('return', Arrow([make_var('T', 'Type')], Arrow([make_var('r', 'T')], ref('T')))) builder.builtin('yield', Arrow([make_var('T', 'Type')], Arrow([make_var('r', 'T')], ref('T')))) # Compile Time Function that makes up the language # We are going to need more like match/value/.... # one function per AST node # The type should be (List[var] -> Type) # Where Var = struct(name: str, type: Type) builder.bind('variable', Builtin('variable', Arrow([make_var('name', 'Symbol'), make_var('type', 'Expression')], ref('Variable')))) builder.builtin('union', Builtin('union', Arrow([make_var('args', 'Variable')], ref('Type')))) builder.builtin('struct', Builtin('struct', Arrow([make_var('args', 'Variable')], ref('Type')))) builder.builtin('lambda', Builtin('lambda', Arrow([make_var('args', 'Variable')], ref('Type')))) # # ATM it will not work because the scope is a dumb dictionary builder.bind('int_add', Builtin('int_add', Arrow([make_var('a', 'Int'), make_var('b', 'Int')], ref('Int')))) builder.bind('*', Builtin('*', Arrow([make_var('a', 'Int'), make_var('b', 'Int')], ref('Int')))) builder.bind('/', Builtin('/', Arrow([make_var('a', 'Int'), make_var('b', 'Int')], ref('Int')))) builder.bind('-', Builtin('-', Arrow([make_var('a', 'Int'), make_var('b', 'Int')], ref('Int')))) # builtin functions builder.bind('+', Builtin('+', Arrow([make_var('a', 'Float'), make_var('b', 'Float')], ref('Float')))) builder.bind('*', Builtin('*', Arrow([make_var('a', 'Float'), make_var('b', 'Float')], ref('Float')))) builder.bind('/', Builtin('/', Arrow([make_var('a', 'Float'), make_var('b', 'Float')], ref('Float')))) builder.bind('-', Builtin('-', Arrow([make_var('a', 'Float'), make_var('b', 'Float')], ref('Float')))) return ctx
def kequal(a: Expression, b: Expression, scope: Scope = Scope(), depth=0) -> bool: r = value_equal(a, b, scope, depth) #if not r: # print(a) # print(b) return r
def __init__(self, module: ir.Module, scope=Scope(), builder=ir): super().__init__() # binding.initialize_all_targets() # default_target = binding.get_default_triple() # target = binding.Target.from_triple('x86_64-pc-linux-gnu') # binding.Target.from_triple('nvptx64-nvidia-cuda') # nvptx64-nvidia-cuda self.module = module self.builder = builder self.scope = scope self.parent = None self.mode = 'codegen' self.binding_name = None self.count = 0
def __init__(self, scope=Scope()): self.scope: Scope = scope self.parent = None
def __init__(self, scope=Scope(), type_hint=None): super().__init__() self.scope = scope self.type_hint = type_hint
def type_trace(expr, scope=Scope(), depth=0, hint=None): tracer = TypeTrace(scope, hint) return tracer.visit(expr, depth)
def run(expr: Expression, ctx=Scope()): return ToStringV(ctx).visit(expr, depth=0)
def print_expr(expr, ctx=Scope()): print(ToStringV.run(expr, ctx))
def to_string(expr, ctx=Scope()): return ToStringV.run(expr, ctx)
def make_scope(name='module_scope') -> Scope(): return __parent_scope.enter_scope(name)