예제 #1
0
 def normal_sexp(self, sexp):
     '''
     we compile macros to a bach lambda and then run them, so some of the resulting values
     can't have the compile-time node types(only native python types and bach runtime types)
     however they are just several of those cases and they're pretty similar
     we convert the results back to normal bach sexp, so we can easily apply other macros
     '''
     PYTHON_BACH_EQUIVALENTS = {
         int: bach_ast.Integer,
         float: bach_ast.Float,
         str: bach_ast.String,
         bool: bach_ast.Boolean
     }
     if isinstance(sexp, list):
         return map(self.normal_sexp, sexp)
     elif type(sexp) in PYTHON_BACH_EQUIVALENTS:
         return PYTHON_BACH_EQUIVALENTS[type(sexp)](sexp)
     elif type(sexp).__name__ == 'BachSymbol':
         return bach_ast.Label(sexp.value)
     elif isinstance(sexp, dict):
         return bach_ast.Dict(map(self.normal_sexp, sexp.keys()),
                              map(self.normal_sexp, sexp.values()))
     elif isinstance(sexp, set):
         return bach_ast.Set(map(self.normal_sexp, sexp))
     else:
         return sexp
예제 #2
0
    def render(self, sexps):
        # mapping = {}
        # if len(self.args) > 0 and isinstance(self.args[-1], bach_ast.Many):
        #     if len(self.args) >= len(sexps) - 1:
        #         for arg, sexp in zip(self.args[:-1], self.sexps[:len(self.args) - 1]):
        #             mapping[arg.label] = sexp
        #         mapping[self.args[-1].label] = sexps[len(self.args) - 1:]
        #     else:
        #         raise MacroMatchError("No enough args for %s" % self.label)
        # else:
        #     if len(self.args) == len(sexps):
        #         for arg, sexp in zip(self.args, sexps):
        #             mapping[arg.label] = sexp
        #     else:
        #         raise MacroMatchError("Expected %d args got %d for %s" % (len(self.args), len(sexps), self.label))
        # value =
        if not self.args:
            args = []
        elif isinstance(self.args[-1], bach_ast.Many):
            args = self.args[:-1] + [bach_ast.Label(self.args[-1].label)]
        else:
            args = self.args

        sexps = [bach_ast.Quote(sexp) for sexp in sexps]
        sexp = bach_ast.Program([[bach_ast.Lambda(args, self.body)] + sexps])
        result = compiler.Compiler().compile_and_eval(sexp,
                                                      stl=bach_stl.load_stl(),
                                                      return_value=True)
        return self.normal_sexp(result)
예제 #3
0
 def convert_operator(self, operator):
     return bach_ast.Label(operator.text)
예제 #4
0
 def convert_dict(self, dict):
     children = [(c.children[0].children[0], c.children[4].children[0]) for c in dict.children[1]]
     elements = []
     for child in children:
         elements += map(self.convert_child, child)
     return [bach_ast.Label('dict')] + elements
예제 #5
0
 def convert_vector(self, sexp):
     return [bach_ast.Label('vector')] + [self.convert_child(c.children[0].children[0]) for c in sexp.children[2].children]
예제 #6
0
 def convert_attr(self, sexp):
     return [bach_ast.Label('attribute')] + map(bach_ast.Label, [s.children[0].text for s in sexp.children[0].children] + [sexp.children[1].text])
예제 #7
0
 def convert_label(self, label):
     return bach_ast.Label(label.text)
예제 #8
0
 def convert_m(self, m):
     return bach_ast.Label(m.text)