Beispiel #1
0
def constification(func, spec):
    # takes an ast.Function node and a list of expressions
    # and replaces the node with a stmt which when executed will define
    # the function and closureify the expressions

    cvars = []
    for east in spec:
        cn = 'ClOsUrE%i__' % c_no()
        replace_ast(func.code, east, cn)
        cvars.append((cn, east))
    func_name = func.name
    subfunc = ast.Function(func.decorators, func_name, func.argnames,
                           func.defaults, func.flags, func.code, func.lineno)
    stmt = [
        ast.Assign([ast.AssName(cn, 'OP_ASSIGN')], east) for cn, east in cvars
    ]
    stmt.append(subfunc)
    stmt.append(ast.Return(ast.Name(func_name, 0)))
    fn = 'CoNsTiFiCaTiOn%i' % f_no()
    dfunc = ast.Function(None, fn, (), (), 0, ast.Stmt(stmt), 0)
    creat = ast.Stmt(
        [dfunc,
         ast_Assign(func_name, ast.CallFunc(ast.Name(fn, 0), ()))])
    # XXX add del(CoNsTiFiCaTiOn)
    make_copy(func, creat)
Beispiel #2
0
def p_funcdecl(p):
    '''funcdecl : type identifier '(' parList ')' block
                | type identifier '('         ')' block'''
    if len(p) == 7:
        p[0] = ast.Function(p[1], p[2], p[4], p[6]).addloc(p.lineno(1))

    else:
        p[0] = ast.Function(p[1], p[2], [], p[5]).addloc(p.lineno(1))
Beispiel #3
0
    def parse_function(self, token, frame):
        symbol = None
        arguments = None

        # Edge - func token only at end
        if not frame:
            _malformed(token)
        # Check first for private
        if isinstance(frame[0], ast.LiteralReference):
            if frame[0].value == ":private":
                frame.pop(0)
            # Should never get here due to pre-parse, but
            else:
                raise errors.ParseError(
                    "{}:{} Function type only supports :private keyword."
                    " Found {}".format(token.getsourcepos().lineno,
                                       token.getsourcepos().colno,
                                       frame[0].value))
        # Should never get here due to pre-parse, but
        if not frame:
            _panic("{}:{} Missing symbol for {}", token)

        if isinstance(frame[0], ast.Symbol):
            symbol = frame.pop(0)
        else:
            _panic("{}:{} Expected symbol for {}", token)

        # Should never get here due to pre-parse, but
        if not frame:
            _panic("{}:{} Missing function arguments", token)
        elif not isinstance(frame[0], ast.CollectionAst):
            _panic("{}:{} Expected function arguments", token)
        else:
            arguments = frame.pop(0)

        # Verify all in collection are symbols
        if not isinstance(arguments, ast.EmptyCollection):
            for x in arguments.value:
                if ((not isinstance(x, ast.Symbol)
                     or x.token.gettokentype() not in self._strict_symtokens)):
                    _panic("{}:{} Invalid symbol in arguments for {}", token)

        expressions = []
        index = 0
        # Get all expressions in function
        for x in frame:
            if not isinstance(x, self._decl_set):
                expressions.append(x)
                index += 1
            else:
                break
        frame = frame[index:]

        hdr = self._locals.get(symbol.name, None)
        if not hdr:
            _panic("{}:{} Function {} not in symbol table", symbol.token)

        frame.insert(0, ast.Function(hdr, expressions, self.input))
        return frame
Beispiel #4
0
 def parse_function(self, declr): 
     func = declr.typ
     return ast.Declaration(
             typ=ast.Function(
                 ret=func.ret,
                 args=func.args,
                 body=self.block()),
             name=declr.name) 
Beispiel #5
0
 def parse(self, parser, tokens):
     tokens.consume_expected('FUNCTION')
     id_token = tokens.consume_expected('NAME')
     tokens.consume_expected('LPAREN')
     arguments = self._parse_params(tokens)
     tokens.consume_expected('RPAREN', 'COLON')
     with enter_scope(parser, 'function'):
         block = Block().parse(parser, tokens)
     if block is None:
         raise ParserError('Expected function body', tokens.current())
     return ast.Function(id_token.value, arguments, block)
Beispiel #6
0
def parse_function(tp: ast.Tuple, tail: Node) -> ast.Function:
    lmd = ast.Lambda(None, tail)
    while True:
        elements = tp.elements
        lmd.params = expand_formals(elements[1:])
        if isinstance(elements[0], ast.Name):
            return ast.Function(elements[0], lmd)
        elif isinstance(elements[0], ast.Tuple):
            tp = elements[0]
            lmd = ast.Lambda(None, lmd)
        else:
            raise ParseError(f'Unsupported ast node type {elements[0]}')
Beispiel #7
0
 def get_func(self, ftok, tstrm):
     h, tk, funcs = self.get_symbol(tstrm)
     if tk.getstr() not in "private" or tk.getstr() not in ":private":
         # print("Processing function {}".format(tk))
         args = self.get_symbols_list(tstrm)
         argv = None
         if args:
             argv = ast.SymbolList(args)
         else:
             argv = ast.EmptyCollection(CollTypes.LIST, [], ftok,
                                        self.input)
         self.values.append(
             ast.Function(ast.FuncHeader(funcs, argv, ftok, self.input),
                          None, self.input))
Beispiel #8
0
def parse(s):
    code = pp.Forward()
    opcode = pp.Or([
        pp.Literal('+'),
        pp.Literal('-'),
        pp.Literal('*'),
        pp.Literal('/'),
        pp.Literal('_'),
        pp.Literal('='),
        pp.Literal('>'),
        pp.Literal('&'),
        pp.Literal('|'),
        pp.Literal('~'),
        pp.Literal('$'),
        pp.Literal('%'),
        pp.Literal('\\'),
        pp.Literal('@'),
        pp.Literal('ø'),
        pp.Literal('p'),
        pp.Literal(':'),
        pp.Literal(';'),
        pp.Literal('!'),
        pp.Literal('?'),
        pp.Literal('#'),
    ]).setParseAction(lambda toks: ast.Opcode(toks[0]))
    number = (pp.Word('1234567890').setParseAction(
        lambda toks: ast.Number(int(toks[0]))))
    str_def = ((pp.Literal('"') + pp.SkipTo(pp.Literal('"'), include=True)
                ).setParseAction(lambda toks: ast.String(toks[1])))
    varname = (pp.Word(
        'qwertyuiopasdfghjklzxcvbnm',
        exact=1).setParseAction(lambda toks: ast.Varname(toks[0])))
    fn_def = pp.Suppress(pp.Literal('[')) + code + pp.Suppress(pp.Literal(']'))
    expr = pp.Or([opcode, number, varname, str_def, fn_def])
    atom = pp.Or([expr])
    code << pp.ZeroOrMore(atom)
    code.setParseAction(lambda toks: ast.Function(toks))
    return code.parseString(s)[0]
Beispiel #9
0
 def parse_declr_expr(self, typ, e):
     '''
     parse an expression as declaration;
 
     e.g. "int *x[8]" when treated as expression will be 
     parsed as `PrefixExpr(op='*', expr=Index(array='x', index=8))`,
     which we want to transform into this:
     `Array(Pointer(typ='int'), cap=8)`
     '''
     while is_type_modifier(e):
         if type(e) == ast.Index:
             cap = int(e.index.val) if e.index is not None else None
             typ = ast.Array(typ=typ, cap=cap)
             e = e.array
         else:
             typ = ast.Pointer(typ=typ)
             e = e.expr
             
     if type(e) == ast.CallExpr: 
         return self.parse_declr_expr(
                 ast.Function(ret=typ or 'void', args=e.args, body=None),
                 e.func)
     else:
         return ast.Declaration(typ=typ, name=e)
Beispiel #10
0
def p_function_definition_02(t):
    '''function_definition : type IDENTIFIER LPAR formal_parameters_list RPAR block'''
    t[0] = ast.Function(t[2], t[1], t[4], t[6])
Beispiel #11
0
def p_function_definition_01(t):
    '''function_definition : type IDENTIFIER LPAR  RPAR block'''
    t[0] = ast.Function(t[2], t[1], ast.FormalParametersList(), t[5])
Beispiel #12
0
def translate(node, st=None, strings=None, funcName=False):
    if isinstance(node, oast.Add):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Add(left, right)

    elif isinstance(node, oast.And):
        left = translate(node.nodes[0], st, strings, funcName)
        right = translate(node.nodes[1], st, strings, funcName)

        return ast.And(left, right)

    elif isinstance(node, oast.Assign):
        # Translate the right hand side first so it can use the older version
        # of the left hand side.
        exp = translate(node.expr, st, strings, funcName)
        var = node.nodes.pop()

        if isinstance(var, oast.AssAttr):
            string = strings.setdefault(var.attrname, ast.String(var.attrname))
            var = translate(var.expr, st, strings, funcName)

            return ast.SetAttr(var, string, exp)

        else:
            var = translate(var, st, strings, funcName)

            return ast.Assign(var, exp)

    elif isinstance(node, oast.AssName):
        return st.getSymbol(node.name, True)

    elif isinstance(node, oast.CallFunc):
        name = translate(node.node, st, strings, True)
        args = [translate(a, st, strings) for a in node.args]

        return ast.FunctionCall(name, *args)

    elif isinstance(node, oast.Class):
        bases = [translate(base, st, strings, funcName) for base in node.bases]

        body = translate(node.code, st, strings, funcName)
        body = ast.BasicBlock(body)

        sym = st.getSymbol(node.name, True)
        name = st.getName(node.name, True)

        # This is here temporarily.  It will be moved to the typify pass
        # later.
        sym['type'] = 'class'

        klass = ast.Class(name, bases, body)

        return ast.Assign(sym, klass)

    elif isinstance(node, oast.Compare):
        left = translate(node.expr, st, strings, funcName)

        op, right = node.ops[0]

        right = translate(right, st, strings, funcName)

        if op == '==':
            return ast.Eq(left, right)

        elif op == '!=':
            return ast.Ne(left, right)

        elif op == 'is':
            return ast.Is(left, right)

    elif isinstance(node, oast.Const):
        return ast.Integer(node.value)

    elif isinstance(node, oast.Dict):
        pairs = {}

        for pair in node.items:
            key, value = pair

            key = translate(key, st, strings, funcName)
            value = translate(value, st, strings, funcName)

            pairs[key] = value

        return ast.Dictionary(pairs)

    elif isinstance(node, oast.Discard):
        return translate(node.expr, st, strings, funcName)

    elif isinstance(node, oast.Div):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Div(left, right)

    elif isinstance(node, oast.Function):
        sym = st.getSymbol(node.name, True)
        name = st.getName(node.name, True)

        sym['type'] = 'function'

        newST = SymbolTable(st)

        argSymbols = [
            newST.getSymbol(argName, True) for argName in node.argnames
        ]

        body = translate(node.code, newST, strings, funcName)
        body = ast.BasicBlock(body)

        fun = ast.Function(name, argSymbols, body, newST)
        fun['simplified'] = False

        st.update(newST)

        return ast.Assign(sym, fun)

    elif isinstance(node, oast.Getattr):
        exp = translate(node.expr, st, strings, funcName)
        name = strings.setdefault(node.attrname, ast.String(node.attrname))

        return ast.GetAttr(exp, name)

    elif isinstance(node, oast.If):
        tests = node.tests
        cond, then = tests.pop(0)

        # Translate the conditional expression.
        cond = translate(cond, st, strings)

        # Snapshot the SymbolTable
        st.snapshot()

        # Translate the 'then' clause.
        then = translate(then, st, strings, funcName)
        then = ast.BasicBlock(then)

        # Roll-back the SymbolTable for the 'else' clause.
        st.rollback()

        # Translate the 'else' clause.
        if len(tests) > 0:
            els = [translate(oast.If(tests, node.else_), st, funcName)]
        else:
            els = translate(node.else_, st, strings, funcName)

        els = ast.BasicBlock(els)

        return ast.If(cond, then, els, st)

    elif isinstance(node, oast.IfExp):
        cond = translate(node.test, st, strings, funcName)
        then = translate(node.then, st, strings, funcName)
        els = translate(node.else_, st, strings, funcName)

        return ast.IfExp(cond, then, els)

    elif isinstance(node, oast.Lambda):
        name = st.getName('lambda', True)

        newST = SymbolTable(st)

        argSymbols = map(lambda name: newST.getSymbol(name, True),
                         node.argnames)

        code = ast.Return(translate(node.code, newST, strings, funcName))
        block = ast.BasicBlock([code])
        fun = ast.Function(name, argSymbols, block, newST)
        fun['simplified'] = False

        st.update(newST)

        return fun

    elif isinstance(node, oast.List):
        elements = []

        for n in node.nodes:
            elements.append(translate(n, st, strings, funcName))

        return ast.List(elements)

    elif isinstance(node, oast.Module):
        # Create a new SymbolTable for this module.
        st = SymbolTable()
        strings = {}

        children = translate(node.node, st, strings, funcName)

        block = ast.BasicBlock(children)
        fun = ast.Function(st.getBIF('main'), [], block, st)

        # Mark the main function as migrated so that it doesn't get moved
        # later.
        fun['simplified'] = True

        return ast.Module([fun], strings)

    elif isinstance(node, oast.Mul):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Mul(left, right)

    elif isinstance(node, oast.Name):
        ret = 'input_int' if node.name == 'input' else node.name

        if ret == 'input_int':
            ret = st.getBIF(ret)

        else:
            if ret == 'True':
                ret = ast.Tru()

            elif ret == 'False':
                ret = ast.Fals()

            else:
                ret = st.getSymbol(ret)

        return ret

    elif isinstance(node, oast.Not):
        operand = translate(node.expr, st, strings, funcName)

        return ast.Not(operand)

    elif isinstance(node, oast.Or):
        left = translate(node.nodes[0], st, strings, funcName)
        right = translate(node.nodes[1], st, strings, funcName)

        return ast.Or(left, right)

    elif isinstance(node, oast.Printnl):
        children = [
            translate(e, st, strings, funcName) for e in node.getChildNodes()
        ]
        children = util.flatten(children)

        return ast.FunctionCall(st.getBIF('print_any'), *children)

    elif isinstance(node, oast.Return):
        return ast.Return(translate(node.value, st, strings, funcName))

    elif isinstance(node, oast.Stmt):
        stmts = [
            translate(s, st, strings, funcName) for s in node.getChildNodes()
        ]

        return util.flatten(stmts)

    elif isinstance(node, oast.Sub):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Sub(left, right)

    elif isinstance(node, oast.Subscript):
        sym = translate(node.expr, st, strings, funcName)
        sub = translate(node.subs[0], st, strings, funcName)

        return ast.Subscript(sym, sub)

    elif isinstance(node, oast.While):
        cond = translate(node.test, st, strings, funcName)

        body = translate(node.body, st, strings, funcName)
        body = ast.BasicBlock(body)

        return ast.While(cond, body, st)

    elif isinstance(node, oast.UnarySub):
        operand = translate(node.expr, st, strings, funcName)

        return ast.Negate(operand)

    else:
        raise Exception("Unsupported AST node encountered: {}".format(
            node.__class__.__name__))
Beispiel #13
0
asm = (Keyword('asm') +
       QuotedString(quoteChar='\"')).setParseAction(lambda t: ast.Asm(t[1]))

goto = (Keyword('goto') + identifier).setParseAction(lambda t: ast.Goto(t[1]))

label = (Keyword('label') +
         identifier).setParseAction(lambda t: ast.Label(t[1]))

comment = ('#' + SkipTo(lineEnd))

line = comment.suppress() | MatchFirst([
    declarevar, declarefn, declare_struct, assignment, function, return_, halt,
    if_, while_, include, asm, goto, label, expr_statement, nop
]) + Literal(';').suppress() + Optional(comment).suppress()

sequence = ZeroOrMore(line).setParseAction(lambda t: ast.Sequence(t.asList()))

block_sequence << ('{' + sequence + '}').setParseAction(lambda t: t[1])

function_args = Group(
    Optional(identifier + ZeroOrMore(Suppress(',') + identifier)))

functionOptions = Group(ZeroOrMore(MatchFirst([Keyword('returns')])))

function << (Keyword('function') + identifier + '(' + function_args + ')' + functionOptions + block_sequence)\
    .setParseAction(lambda t: ast.Function(t[1], t[3], t[6], options = t[5]))

# lambda q: ast.Function(t[1], t[3], + t[5] )
program = sequence + StringEnd()
Beispiel #14
0
is_undent = False
rets = {
    'System print': 'void',
    'Float -': 'Float',
    'Float *': 'Float',
    'Float +': 'Float',
    'Float /': 'Float',
    'Int -': 'Int',
    'Int *': 'Int',
    'Int +': 'Int',
    'Int /': 'Int',
    '$z 0': 'void'
}
index = {'$z': ast.Call('System', 'print', [])}
tree = ast.Program(
    [ast.Definition('$main', ast.Function(ast.Args([]), [], ret='int'), True)])
anon_actor_num = 0
buff = ''  # For names and values


def parse(source):
    while True:
        try:
            q = parse_top_level(source)
            #raise_error(source)
            tree.append(q)
        except ValueError:
            break
    for i in tree:
        if isinstance(i, ast.Actor):
            tree[-1].value.append(ast.Call('$z', str(anon_actor_num), []))
Beispiel #15
0
 def p_expression_fun(self, p):
     """
     expression : function LPAREN expression RPAREN
                | function LPAREN sequence RPAREN
     """
     p[0] = ast.Function(p[1], p[3], p.lexer.lexer.lineno)
Beispiel #16
0
    if (args[0] == 'run'):
        args = args[1:]
except IndexError:
    print('Welcome to the Rhea REPL!')
    print r'''____/\\\\\\\\\______/\\\________/\\\__/\\\\\\\\\\\\\\\_____/\\\\\\\\\____
 __/\\\///////\\\___\/\\\_______\/\\\_\/\\\///////////____/\\\\\\\\\\\\\__
  _\/\\\_____\/\\\___\/\\\_______\/\\\_\/\\\______________/\\\/////////\\\_
   _\/\\\\\\\\\\\/____\/\\\\\\\\\\\\\\\_\/\\\\\\\\\\\_____\/\\\_______\/\\\_
    _\/\\\//////\\\____\/\\\/////////\\\_\/\\\///////______\/\\\\\\\\\\\\\\\_
     _\/\\\____\//\\\___\/\\\_______\/\\\_\/\\\_____________\/\\\/////////\\\_
      _\/\\\_____\//\\\__\/\\\_______\/\\\_\/\\\_____________\/\\\_______\/\\\_
       _\/\\\______\//\\\_\/\\\_______\/\\\_\/\\\\\\\\\\\\\\\_\/\\\_______\/\\\_
        _\///________\///__\///________\///__\///////////////__\///________\///__
        '''
    tree = ast.Initialization(True, '$main',
                              ast.Function(ast.Args([]), [], ret='int'))
    while True:
        sys.stdout.write('rhea> ')
        line = sys.stdin.readline()
        if line == '':
            print('\nGoodbye!')
            sys.exit(0)
        line = line[:-1] + ' \n'
        parserizer.loc = 0
        parserizer.source = line
        tmptree = parserizer.parse_expr()
        old = tree.value.get_last()
        if isinstance(old, ast.Send):
            if isinstance(old.args[0], ast.IntLiteral) or isinstance(
                    old.args[0], ast.FloatLiteral) or isinstance(
                        old.args[0], ast.Lookup):
Beispiel #17
0
def gen_actor(body):
    gen_define('$z' + str(parser.anon_actor_num),
               ast.Function(ast.Args([]), body, ret='void'), True)
Beispiel #18
0
def p_function(p):
    """function : FUNCTION LROUND var_list RROUND LCURLY summary stmt_list RETURN LROUND var_list RROUND RCURLY"""
    p[0] = ast.Function(p[3], p[10], p[7], p[6])