Ejemplo n.º 1
0
    def generateSetExec(s, m, loc, prefix, target):
        if not target:
            return Error(loc, u"Missing target to import")
        if prefix:
            if type(target[0]) == reader.SymbolExp:
                if target[
                        0].isAtom:  # FIXME: This check should occur even if prefix does not
                    return Error(target[0].loc,
                                 u"Expected a symbol after \"import\"")
                newSymbol = reader.SymbolExp(target[0].loc, True)
                newSymbol.content = target[0].content
                target = [newSymbol] + target[1:]
            target = prefix + target

        if len(target) == 1:
            return Error(
                target[0].loc,
                u"import expects either multiple symbols or a \"from\" clause")

        if type(target[-1]) != reader.SymbolExp or not target[-1].isAtom:
            return Error(target[-1].loc,
                         u"End of import path needs to be an atom")

        symbol = execution.AtomLiteralExec(target[-1].loc, target[-1].content)

        return execution.SetExec(loc, True, False, False, False, None, symbol,
                                 m.process(target))
Ejemplo n.º 2
0
 def apply(s, m, left, node, right, _):
     export = False
     if left:
         if not (len(left) == 1 and isSymbol(left[0], "export")):
             return Error(node.loc,
                          "Stray garbage before \"%s\"" % s.symbol())
         export = True
     if not right:
         return Error(node.loc, u"Emptiness after \"%s\"" % s.symbol())
     macroGroup = right[0]
     if type(macroGroup) == reader.SymbolExp:
         # TODO: Consider only allowing this if atom keys. TODO: Do something more sensible when this fails?
         macroObject = m.process(right).eval(execution.profileScope)
         try:
             macroList = macroObject.apply(
                 execution.AtomLiteralExec(node.loc,
                                           execution.macroExportList))
         except execution.InternalExecutionException as e:
             raise execution.ExecutionException(macroGroup.loc,
                                                u"macro load", unicode(e))
         if type(macroList) != list:
             return Error(
                 macroGroup.loc,
                 u"macro import path did not resolve to a valid module")
         else:
             payload = None
             importObject = macroObject
             if isinstance(importObject, execution.LazyMacroLoader
                           ):  # TODO: What about module objects?
                 importObject = importObject.importObject()
             if importObject:
                 payload = execution.ImportAllExec(
                     node.loc,
                     execution.StoredLiteralExec(node.loc, importObject),
                     export)
             return ([],
                     UserMacroList(node.loc, macroList, export, s.profile,
                                   payload), [])
     elif type(macroGroup) == reader.ExpGroup:
         if len(right) > 1:
             return Error(
                 node.loc,
                 u"Stray garbage after \"%s (group)\"" % s.symbol())
         macros = m.makeArray(macroGroup)
         return ([],
                 UserMacroList(
                     node.loc,
                     [ast.eval(execution.defaultScope)
                      for ast in macros], export, s.profile), [])
     else:
         return Error(
             node.loc,
             u"Expected a path or a (group) after \"%s\"" % s.symbol())
Ejemplo n.º 3
0
    def apply(s, m, left, node, right, _):
        for case in switch(type(node)):
            if case(reader.QuoteExp):
                node = execution.StringLiteralExec(node.loc, node.content)
            elif case(reader.NumberExp):
                value = node.integer
                if node.dot:
                    value += "."
                if node.decimal is not None:
                    value += node.decimal
                node = execution.NumberLiteralExec(node.loc, float(value))
            elif case(reader.SymbolExp):
                if node.isAtom:
                    node = execution.AtomLiteralExec(node.loc, node.content)
                else:
                    node = execution.VarExec(node.loc, node.content)
            else:
                return Error(
                    node.loc,
                    "Internal error: AST node of indecipherable type %s found in a place that shouldn't be possible"
                    % (type(node).__name__))

        return (left, node, right)
Ejemplo n.º 4
0
 def apply(s, m, left, node, right, tracker):
     isLet = False
     isMethod = False
     isField = False
     isExport = False
     target = None
     for idx in range(len(left)):
         if isSymbol(left[idx], u"let"):
             isLet = True
         elif isSymbol(left[idx], u"method"):
             isMethod = True
         elif isSymbol(left[idx], u"field"):
             isField = True
         elif isSymbol(left[idx], u"export"):
             isExport = True
         else:
             break
     if isLet and isExport:
         return Error(node.loc,
                      "Cannot use \"let\" and \"export\" together")
     if left:
         left = left[idx:]
     if len(left) == 0:
         return Error(node.loc, "Missing name in =")
     key = left[-1]
     if len(left) > 1:
         target = m.process(left[:-1])
         key = m.process([key])
     else:  # Currently under all circumstances a = b is a flat atom assignment
         if type(key) != reader.SymbolExp or key.isAtom:
             return Error(key.loc, "Assigned name must be alphanumeric")
         key = execution.AtomLiteralExec(key.loc, key.content)
     value = m.process(right, tracker)
     return ([],
             execution.SetExec(node.loc, isLet, isMethod, isField, isExport,
                               target, key, value), [])
Ejemplo n.º 5
0
 def apply(s, m, left, node, right, tracker):
     if not right:
         return Error(node.loc, u"Emptiness after \"match\"")
     lines = right.pop(0)
     if type(lines) != reader.ExpGroup:
         return Error(node.loc, u"Expected a (group) after \"match\"")
     result = []
     for stmIdx in range(len(lines.statements) if lines.statements else 0):
         stm = lines.statements[stmIdx]
         if not stm.nodes:  # Match is "like code" so may contain a blank line...?
             continue
         eqIdx = None  # Find = sign
         for idx in range(len(stm.nodes)):
             if isSymbol(stm.nodes[idx], '='):
                 eqIdx = idx
                 break
         if eqIdx is None:
             return Error(
                 node.loc,
                 u"match line #%d does not have an =" % (stmIdx + 1))
         eqNode = stm.nodes[eqIdx]
         eqLeft = stm.nodes[:eqIdx]
         eqRight = stm.nodes[eqIdx + 1:]
         if not eqLeft:
             return Error(
                 node.loc,
                 u"On match line #%d, left of = is blank" % (stmIdx + 1))
         if len(eqLeft) > 2:
             return Error(
                 node.loc,
                 u"On match line #%d, left of = has too many symbols. Try adding parenthesis?"
                 % (stmIdx + 1))
         if not eqRight:
             return Error(
                 node.loc,
                 u"On match line #%d, right of = is blank" % (stmIdx + 1))
         target = eqLeft.pop(0)
         unpacksExp = None
         unpacks = []
         if eqLeft:
             unpacksExp = eqLeft[0]
             foundUnpack = False
             if type(unpacksExp) == reader.SymbolExp:
                 unpacks = [
                     execution.AtomLiteralExec(unpacksExp.loc,
                                               unpacksExp.content)
                 ]
                 foundUnpack = True
             elif type(unpacksExp) == reader.ExpGroup:
                 for statement in unpacksExp.statements:
                     if not statement.nodes or type(
                             statement.nodes[0]) != reader.SymbolExp:
                         foundUnpack = False
                         break
                     unpacks.append(
                         execution.AtomLiteralExec(
                             statement.nodes[0].loc,
                             statement.nodes[0].content))
                     foundUnpack = True
             if not foundUnpack:
                 return Error(
                     node.loc,
                     u"On match line #%d, variable unpack list on left of = is garbled"
                     % (stmIdx + 1))
         if isSymbol(target, '_'):
             if unpacksExp:
                 return Error(
                     node.loc,
                     u"On match line #%d, variable unpack list used with _"
                     % (stmIdx + 1))
             target = None
         elif isSymbol(target, 'array'):
             if not unpacksExp:
                 return Error(
                     node.loc,
                     u"On match line #%d, \"array\" used but no unpack list found"
                     % (stmIdx + 1))
             target = None
         if target:
             target = m.process([target])
         tempStatement = m.process(eqRight, tracker)
         result.append(MatchCase(target, unpacks, tempStatement))
     return (left, execution.MakeMatchExec(node.loc, result), right)