def __create_type(name, cases): import sidekick as sk namespace = {} for casename, typename in cases: if typename is None: namespace[casename] = sk.opt() else: typevalue = type_from_name(typename) namespace[casename] = sk.opt(typevalue) return type(name, (sk.Union, ), namespace)
def adt(name, **opts): """ Cria um tipo tagged union. Args: name (str): Nome do tipo. states (dict): Dicionário de {str: bool} que diz para cada estado, se o construtor precisa de argumentos ou não. Examples: >>> adt('Maybe', Just=None, Nothing=object) # doctest: +ELLIPSIS <type Maybe> """ validate_names(name, opts) ns = UnionMeta.__prepare__(name, (sk.Union, )) for opt_name, value in opts.items(): if value is None: ns[opt_name] = sk.opt() else: ns[opt_name] = sk.opt(value) return UnionMeta(name, (sk.Union, ), ns)
class Stmt(Union): Assign = sk.opt(name=str, expr=Expr) Export = sk.opt(names=list) Fundef = sk.opt(name=str, fargs=list, expr=Expr) Import = sk.opt(module=str, names=dict) ImportAll = sk.opt(module=str) Opdef = sk.opt(symbol=str, function=str, assoc=Assoc, precedence=int) Typedef = sk.opt(name=str, options=list) def required_symbols(self, acc=None): acc = set() if acc is None else acc if isinstance(self, Assign): self.expr.required_symbols(acc) elif isinstance(self, Fundef): acc.update(self.expr.required_symbols() - set(self.fargs)) return acc
class Stmt(Union): Assign = sk.opt(name=str, expr=Expr) # names : lista de strings com os símbolos exportados Export = sk.opt(names=list) # name : nome da função # farsg : lista de strings com o nome de cada argumento # expr : corpo da função Fundef = sk.opt(name=str, fargs=list, expr=Expr) # module : nome do módulo # names : dicionário de nome original para alias de todos # valores importados Import = sk.opt(module=str, names=dict) # module : nome do módulo ImportAll = sk.opt(module=str) # symbol : símbolo do operador (ex: '+') # function : nome da função responsável por implementar o operador # assoc : associatividade (esquerda ou direita) # precedence : nível de precedência do operador Opdef = sk.opt(symbol=str, function=str, assoc=Assoc, precedence=int) # name : nome do tipo # options : mapa com o nome de cada opção associada às variáveis # exigidas pelo construtor Typedef = sk.opt(name=str, options=dict) def required_symbols(self, acc=None): acc = set() if acc is None else acc if self.is_assign: self.expr.required_symbols(acc) elif self.is_fundef: acc.update(self.expr.required_symbols() - set(self.fargs)) elif self.is_export: acc.update(self.names) elif self.is_opdef: acc.add(self.function) return acc
class Expr(Union): And = sk.opt(left=this, right=this) Atom = sk.opt(object) BinOp = sk.opt(op=str, left=this, right=this) Call = sk.opt(caller=this, fargs=list) Case = sk.opt(value=this, cases=dict) Classname = sk.opt(str) Constructor = sk.opt(classname=str, value=this) Enum = sk.opt(name=str) If = sk.opt(cond=this, then=this, other=this) Let = sk.opt(expr=this, binds=dict) List = sk.opt(data=list) Name = sk.opt(str) Not = sk.opt(this) Op = sk.opt(op=str, left=this, right=this) Or = sk.opt(left=this, right=this) Record = sk.opt(data=dict) Tuple = sk.opt(data=tuple) def required_symbols(self, acc=None): """ Retorna a lista de símbolos externos necessários para avaliar a expressão. """ acc = set() if acc is None else acc return self.visit_nodes(required_symbols_visitor, acc)
class Stmt(sk.Union): Assign = sk.opt(name=str, expr=Expr)
class Expr(sk.Union): Atom = sk.opt(object) BinOp = sk.opt(op=str, left=Expr, right=Expr) FCall = sk.opt(name=str, fargs=list)
class Stmt(sk.Union): Assign = sk.opt(name=str, value=Expr) FDef = sk.opt(name=str, args=list, body=list) Return = sk.opt(Expr)
class Expr(sk.Union): Atom = sk.opt(object) FCall = sk.opt(name=str, fargs=list) Symbol = sk.opt(str)
class Expr(sk.Union): Number = sk.opt(int) BinOp = sk.opt(op=str, left=Expr, right=Expr) FCall = sk.opt(name=str, fargs=list)