Esempio n. 1
0
def parse_let_family(tp: ast.Tuple) -> ast.Node:
    if len(tp.elements) < 3:
        raise ParseError(
            f'{tp.elements[0]}: bad syntax, no expression in body')
    elem = tp.elements[1]
    if not isinstance(elem, ast.Tuple):
        raise ParseError(
            f'{tp.elements[0]}: bad syntax, expected bindings, given: {elem}')
    bindings: List[Node] = elem.elements
    patterns: List[ast.Name] = []
    exprs: List[Node] = []
    for i, binding in enumerate(bindings):
        if isinstance(binding, ast.Tuple):
            if len(binding.elements) == 2:
                if isinstance(binding.elements[0], ast.Name):
                    patterns.append(binding.elements[0])
                    exprs.append(parse_node(binding.elements[1]))
                    continue
        raise ParseError(
            f'{tp.elements[0]}: bad syntax, not an identifer and expression for a binding {binding}'
        )
    body = ast.Block(parse_list(tp.elements[2:]))
    name = tp.elements[0]
    if not isinstance(name, ast.Name):
        raise ParseError(f'expected a Name, given {name}')
    if name.identifier == constants.LET:
        return ast.Let(patterns, exprs, body)
    elif name.identifier == constants.LET_STAR:
        return ast.LetStar(patterns, exprs, body)
    elif name.identifier == constants.LET_REC:
        return ast.LetRec(patterns, exprs, body)
    else:
        raise ParseError(f'{tp.elements[0]}: should not be here')
Esempio n. 2
0
def p_ifstmt(p):
    '''ifstmt : TKIF '(' cond_expr ')' block TKELSE block
              | TKIF '(' cond_expr ')' block '''
    if len(p) == 8:
        p[0] = ast.IfStmt(p[3], p[5], p[7]).addloc(p.lineno(1))
    else:
        p[0] = ast.IfStmt(p[3], p[5], ast.Block()).addloc(p.lineno(1))
Esempio n. 3
0
 def parse_block(self):
     stats = self.parse_stats()
     block = ast.Block(stats)
     if self.lex.look_ahead().kind == lexer.TokenKind.KW_RETURN:
         retstat = self.parse_retstat()
         block.append_stat(retstat)
     return block
Esempio n. 4
0
 def block(self):
     self.expect('{')
     stmts = []
     while not self.accept('}'):
         stmts.append(self.statement()) 
     self.expect('}')
     return ast.Block(stmts)
Esempio n. 5
0
    def parse_block(self):
        if not isinstance(self.current, tokens.LBRACE):
            raise ParserError(
                f"Expected {'{'} after function, found `{self.current}`")
        self.step()
        statements = []
        while not isinstance(self.current, tokens.EOF):
            if isinstance(self.current, tokens.SEMICOLON):
                self.step()
                continue
            if isinstance(self.current, tokens.LET):
                stmt = self.parse_let()
            elif isinstance(self.current, tokens.FUNC):
                stmt = self.parse_function_literal()
            elif isinstance(self.current, tokens.RETURN):
                stmt = self.parse_return()
            elif isinstance(self.current, tokens.IF):
                stmt = self.parse_conditional()
            elif isinstance(self.current, tokens.LBRACE):
                stmt = self.parse_block()
            elif isinstance(self.current, tokens.RBRACE):
                break
            else:
                stmt = self.parse_expr()

            statements.append(stmt)

        self.step()

        return ast.Block(statements)
Esempio n. 6
0
 def parse_block_expression(self, expect_delim):
   self.expect_word('bk')
   name = self.expect_type(Token.IDENTIFIER)
   subject = [self.get_functino_subject()]
   signature = self.parse_functino_signature(subject, False)
   methods = self.parse_functino_tail(signature, subject)
   self.expect_word('in')
   body = self.parse_word_expression(expect_delim)
   return ast.Block(name, methods, body)
Esempio n. 7
0
    def block(self):
        """block : declarations compound_statement
        """

        # declarations
        declaration_nodes = self.declarations()
        # compound BEGIN...END
        compound_statement_node = self.compound_statement()
        node = ast.Block(declaration_nodes, compound_statement_node)
        return node
Esempio n. 8
0
 def block(self):
     if self.currtok[0] == "PCTLBRA":
         self.currtok = next(self.tokens)
         b = self.statements()
         if self.currtok[0] == "PCTRBRA":
             self.currtok = next(self.tokens)
             return ast.Block(b)
         else:
             raise CLiteSyntaxError("Right Brace expected", self.currtok[1])
     else:
         raise CLiteSyntaxError("Left brace expected", self.currtok[1])
Esempio n. 9
0
    def block(self):
        self.expect(T.LEFT_BRACE)
        self.root.push_scope()
        stmts = []
        while self.peek().type != T.RIGHT_BRACE:
            stmts.append(self.statement())

        self.expect(T.RIGHT_BRACE)
        self.root.pop_scope()

        return ast.Block(stmts)
Esempio n. 10
0
def semiAsExpr(block):
    '''
	Convert a list of expressions to a single expression, possibly a Block
	'''
    block = list(filter(lambda x: x is not None, block))

    if len(block) == 0:
        return ast.Value(None)
    elif len(block) == 1:
        return block[0]
    else:
        return ast.Block(block)
Esempio n. 11
0
    def parse_loop(self, cur):
        always = self.block()

        if self.maybe("while"):
            cond, bl, th, el = self.parse_while()

            return ast.Loop(ast.Block([
                always,
                ast.If(cond, bl, semiAsExpr([th, ast.Branch("break")]))
            ]),
                            el=el).set_origin(cur)
        else:
            return ast.Loop(always).set_origin(cur)
Esempio n. 12
0
def parse_define(tp: ast.Tuple) -> ast.Define:
    elements = tp.elements
    if len(elements) < 3:
        raise ParseError(f'define: bad syntax (missing expressions) {tp}')
    if isinstance(elements[1], ast.Name):
        if len(elements) > 3:
            raise ParseError(f'define: bad syntax (multiple expressions) {tp}')
        return ast.Define(elements[1], parse_node(elements[2]))
    elif isinstance(elements[1], ast.Tuple):
        tail = ast.Block(parse_list(elements[2:]))
        function = parse_function(elements[1], tail)
        return ast.Define(function.caller, function)
    else:
        raise ParseError(f'Unsupported ast node type: {elements[1]}')
Esempio n. 13
0
def parse_lambda(tp: ast.Tuple) -> ast.Lambda:
    elements = tp.elements
    if len(elements) < 3:
        raise ParseError(f'lambda: bad syntax: {tp}')
    pattern = elements[1]
    body = ast.Block(parse_list(elements[2:]))
    if isinstance(pattern, ast.Name):
        return ast.Lambda(pattern, body)
    elif isinstance(pattern, ast.Tuple):
        formals = expand_formals(pattern.elements)
        if isinstance(formals, ast.Pair) or formals is ast.NULL_PAIR:
            return ast.Lambda(formals, body)
        else:
            raise ParseError('lambda: illegal use of \'.\'')
    else:
        raise ParseError(f'Unsupported ast node type: {pattern}')
Esempio n. 14
0
    def block(self):
        '''
        Block -> '{' Statements '}'
        :return: a Block object
        '''
        # match/consume the opening brace
        self.curr_tok = self.lex_gen.__next__()

        stmts = self.statements()

        if self.curr_tok[0] != values.RBRACE:
            raise CliteSyntaxError('} expected')

        self.curr_tok = self.lex_gen.__next__()

        return ast.Block(stmts)
Esempio n. 15
0
def p_block(p):
    '''block : '{' vardecllist stmtlist '}'
             | '{' vardecllist '}'
             | '{' stmtlist '}'
             | '{' '}' '''
    p[0] = ast.Block().addloc(p.lineno(1))
    if len(p) == 4:
        for y in p[2]:
            if isinstance(y, ast.VarDecl):
                p[0].addVardecl(y)
            else:
                p[0].addStatement(y)
    elif len(p) == 5:
        for vd in p[2]:
            p[0].addVardecl(vd)
        for st in p[3]:
            p[0].addStatement(st)
Esempio n. 16
0
    def block(self, level):
        """
        Block -> '{' Statements '}'
        :param level: indicates level of statements in block; type(level) - int
        :return: An ast.Block object
        :raise CliteSyntaxError if an unexpected token is seen
        """
        # Consume the opening brace identifying the start of a block
        self.curr_tok = self.lex.__next__()

        statements = self.statements(level)

        # Match right closing brace
        if self.curr_tok[self.CODE] != tokens.SINGLE_TOKENS[tokens.RBRACE][self.CODE]:
            raise errors.CliteSyntaxError("'}' expected!", self.curr_tok[self.LINE])
        # Consume right closing brace
        self.curr_tok = self.lex.__next__()

        return ast.Block(statements, level)
Esempio n. 17
0
 def block_stmt(self) -> ast.Block:
     self.check_eof("Expected { for block statement.")
     toks = TokenList()
     if not toks.add(self.match(token.LBRACE)):
         raise ParseException("Expected { for block statement.")
     # Snapshot the current scope (before block)
     previous_scope = self.symbol_tree.take_snapshot()
     # Parse all block statments
     statements : typing.List[ast.BaseNode] = []
     while self.peek().type != token.RBRACE:
         self.check_eof("Expected statement for block body.")
         statements.append(self.stmt())
     self.check_eof("missing } for block statement")
     if not toks.add(self.match(token.RBRACE)):
         raise ParseException("Missing } for block statement.")
     # Store block scope and ...
     # leave block scope == restore scope snapshot
     block_scope = self.symbol_tree.take_snapshot()
     self.symbol_tree.restore_snapshot(previous_scope)
     return ast.Block(toks, statements)
Esempio n. 18
0
    def block(self):
        '''
		Parses a "block", which is an expression which prioritizes curly-brace
		blocks over object literals and considers the semicolon to end the
		expression rather than continue it.
		'''

        cur = self.cur
        if self.maybe("{"):
            vars = []
            with common.stack(self.scope, vars):
                b = self.semichain()
            self.expect("}")
            if len(vars) > 0:
                return ast.Block(b, vars).set_origin(cur)
            else:
                return semiAsExpr(b)
        else:
            x = self.expr()
            self.maybe(";")
            return x
Esempio n. 19
0
    def block(self):
        '''
        Block --> { Statement }
        :return: ast.Block
        '''
        # need '{'
        if self.curr_tok[0] != lexer.Lexer.LCBRACK:
            print("Error: '{' expected found:", self.curr_tok[1], "on line",
                  self.curr_tok[2])
            sys.exit(1)

        self.curr_tok = next(self.lex)

        stmt = self.statements()

        # need '}'
        if self.curr_tok[0] != lexer.Lexer.RCBRACK:
            print("Error: '}' expected found:", self.curr_tok[1], "on line",
                  self.curr_tok[2])
            sys.exit(1)

        self.curr_tok = next(self.lex)

        return ast.Block(stmt)
Esempio n. 20
0
 def p_block(self, p):
     """block : LBRACE source_elements RBRACE"""
     p[0] = ast.Block(p[2])
Esempio n. 21
0
 def p_expression_block(self, parse):
     """
     expression : LBRACE block_list RBRACE
     """
     parse[0] = AST.Block(expr_list=parse[2])
Esempio n. 22
0
def block(stat):
    if isinstance(stat, ast.Block):
        return stat
    assert isinstance(stat, ast.Statement)
    return ast.Block([stat]).at(stat)
Esempio n. 23
0
def p_block(p):
    '''statement : LBRACE RBRACE
                 | LBRACE statements RBRACE'''
    stat = [] if len(p) == 3 else p[2]
    p[0] = ast.Block(stat).at(loc(p))
Esempio n. 24
0
def statements_statement(s):
    return ast.Block([s[0]])
Esempio n. 25
0
 def p_expression_block(self, parse):
     '''
     expression : LBRACE block_list RBRACE
     '''
     parse[0] = AST.Block(expression_list=parse[2])
Esempio n. 26
0
def statements(s):
    return ast.Block(s[0].getastlist() + [s[1]])
Esempio n. 27
0
def p_fundef(p):
    '''fundef : funheader LBRACE RBRACE
              | funheader LBRACE statements RBRACE'''
    name, _type = p[1]
    body = ast.Block(p[3] if len(p) == 5 else [])
    p[0] = ast.FunDef(False, name, _type, body).at(loc(p, 1))
Esempio n. 28
0
def parse_begin(tp: ast.Tuple) -> ast.Begin:
    return ast.Begin(ast.Block(parse_list(tp.elements[1:])))
Esempio n. 29
0
def parse_block(tp: ast.Tuple) -> ast.Block:
    return ast.Block(parse_list(tp.elements))
Esempio n. 30
0
def p_fundef_static(p):
    '''fundef : STATIC funheader LBRACE RBRACE
              | STATIC funheader LBRACE statements RBRACE'''
    name, _type = p[2]
    body = ast.Block(p[4] if len(p) == 6 else [])
    p[0] = ast.FunDef(True, name, _type, body).at(loc(p, 2))