Example #1
0
 def parse_call_expression(self):
   recv = self.parse_atomic_expression()
   while True:
     is_async = False
     if self.at_punctuation('->'):
       self.expect_punctuation('->')
       is_async = True
     elif self.at_punctuation('.'):
       self.expect_punctuation('.')
     if self.at_punctuation('('):
       selector = Parser._SAUSAGES
       start = '('
       end = ')'
     elif self.at_punctuation('['):
       selector = Parser._SQUARE_SAUSAGES
       start = '['
       end = ']'
     else:
       break
     prefix = [
       ast.Argument(data._SUBJECT, recv),
       ast.Argument(data._SELECTOR, ast.Literal(selector)),
       ast.Argument(data._TRANSPORT, ast.Literal(data._ASYNC if is_async else data._SYNC))
     ]
     rest = self.parse_arguments(start, end)
     recv = ast.Invocation(prefix + rest)
   return recv
Example #2
0
 def parse_atomic_expression(self):
   if self.at_type(Token.LITERAL):
     value = self.expect_type(Token.LITERAL)
     result = ast.Literal(value)
     if isinstance(value, data.DecimalFraction):
       # While the infrastructure is not in place to create floats without
       # magic we insert a new_float invocation in the parser.
       result = ast.Invocation([
         ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["ctrino"])))),
         ast.Argument(data._SELECTOR, ast.Literal(data.Operation.infix("new_float_32"))),
         ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)),
         ast.Argument(0, result)
       ])
     return result
   elif self.at_type(Token.IDENTIFIER):
     return self.parse_variable()
   elif self.at_punctuation('('):
     self.expect_punctuation('(')
     result = self.parse_expression(False)
     self.expect_punctuation(')')
     return result
   elif self.at_punctuation('['):
     return self.parse_array_expression()
   elif self.at_punctuation('{'):
     return self.parse_sequence_expression()
   elif self.at_word('null'):
     self.expect_word('null')
     return ast.Literal(None)
   elif self.at_word('true'):
     self.expect_word('true')
     return ast.Literal(True)
   elif self.at_word('false'):
     self.expect_word('false')
     return ast.Literal(False)
   elif self.at_word('subject'):
     self.expect_word('subject')
     return ast.Literal(data._SUBJECT)
   elif self.at_word('selector'):
     self.expect_word('selector')
     return ast.Literal(data._SELECTOR)
   elif self.at_word('transport'):
     self.expect_word('transport')
     return ast.Literal(data._TRANSPORT)
   elif self.at_word('async'):
     self.expect_word('async')
     return ast.Literal(data._ASYNC)
   elif self.at_word('sync'):
     self.expect_word('sync')
     return ast.Literal(data._SYNC)
   elif self.at_word('module'):
     self.expect_word('module')
     return ast.CurrentModule()
   elif self.at_type(Token.QUOTE):
     return self.parse_quote()
   else:
     raise self.new_syntax_error()
Example #3
0
 def parse_new_expression(self, expect_delim):
   self.expect_word('new')
   cons = self.parse_atomic_expression()
   args = self.parse_arguments('(', ')')
   self.expect_statement_delimiter(expect_delim)
   prefix = [
     ast.Argument(data._SUBJECT, cons),
     ast.Argument(data._SELECTOR, ast.Literal(Parser._NEW)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC))
   ]
   return ast.Invocation(prefix + args)
Example #4
0
 def parse_operator_expression(self):
   left = self.parse_unary_expression()
   while self.at_type(Token.OPERATION):
     (selector, is_async, rest) = self.parse_operator_tail()
     prefix = [
       ast.Argument(data._SUBJECT, left),
       ast.Argument(data._SELECTOR, ast.Literal(selector)),
       ast.Argument(data._TRANSPORT, ast.Literal(data._ASYNC if is_async else data._SYNC))
     ]
     left = ast.Invocation(prefix + rest)
   return left
Example #5
0
 def parse_unary_expression(self):
   if self.at_type(Token.OPERATION):
     (name, is_async) = self.expect_type(Token.OPERATION)
     selector = data.Operation.prefix(name)
     subject = self.parse_unary_expression()
     args = [
       ast.Argument(data._SUBJECT, subject),
       ast.Argument(data._SELECTOR, ast.Literal(selector)),
       ast.Argument(data._TRANSPORT, ast.Literal(data._ASYNC if is_async else data._SYNC))
     ]
     return ast.Invocation(args)
   else:
     return self.parse_call_expression()
Example #6
0
 def parse_for_expression(self, expect_delim):
   self.expect_word('for')
   sig = self.parse_signature()
   self.expect_word('in')
   elms = self.parse_expression(False)
   self.expect_word('do')
   body = self.parse_expression(expect_delim)
   thunk = ast.Lambda([ast.Method(sig, body)])
   return ast.Invocation([
     ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "for"])))),
     ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)),
     ast.Argument(0, elms),
     ast.Argument(1, thunk),
   ])
Example #7
0
 def parse_while_expression(self, expect_delim):
   self.expect_word('while')
   cond = self.parse_expression(False)
   self.expect_word('do')
   body = self.parse_expression(expect_delim)
   methods = [
     ast.Lambda.method(cond, data.Operation.infix('keep_running?')),
     ast.Lambda.method(body, data.Operation.infix('run!'))
   ]
   return ast.Invocation([
     ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "while"])))),
     ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)),
     ast.Argument(0, ast.Lambda(methods)),
   ])
Example #8
0
    def parse_method_call(self, left):
        expr = ast.MethodCall(self.cur_tok, left, [])

        while self.peek_in(self.arg_tokens) or self.peek_in(
                token.keywords.values()):
            self.next()

            if self.cur_in(token.keywords.values()):
                expr.pattern.append(ast.Identifier(self.cur_tok))
                continue

            arg = lambda val: ast.Argument(self.cur_tok, val)

            handlers = {
                token.ID: lambda: ast.Identifier(self.cur_tok),
                token.LPAREN: lambda: arg(self.parse_grouped_expr()),
                token.NUM: lambda: arg(self.parse_num()),
                token.NULL: lambda: arg(self.parse_null()),
                token.TRUE: lambda: arg(self.parse_bool()),
                token.FALSE: lambda: arg(self.parse_bool()),
                token.STR: lambda: arg(self.parse_string()),
                token.PARAM: lambda: arg(ast.Identifier(self.cur_tok)),
                token.LSQUARE: lambda: arg(self.parse_array_or_map()),
                token.LBRACE: lambda: arg(self.parse_block_literal()),
            }

            handler = handlers[self.cur_tok.type]
            expr.pattern.append(handler())

        if len(expr.pattern) == 0:
            self.err("expected at least one item in a pattern")
            return None

        return expr
Example #9
0
 def parse_argument(self, default_tag):
   if self.at_type(Token.TAG):
     tag = self.expect_type(Token.TAG)
   else:
     tag = default_tag
   value = self.parse_expression(False)
   return ast.Argument(tag, value)
Example #10
0
 def parse_when_expression(self, expect_delim):
   self.expect_word('when')
   self.expect_word('def')
   sig = self.parse_signature()
   self.expect_punctuation(':=')
   value = self.parse_expression(False)
   self.expect_word('do')
   body = self.parse_expression(expect_delim)
   thunk = ast.Lambda([ast.Method(sig, body)])
   return ast.Invocation([
     ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "when_def"])))),
     ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)),
     ast.Argument(0, value),
     ast.Argument(1, thunk),
   ])
Example #11
0
 def parse_signal_expression(self, expect_delim):
   if self.at_word('leave'):
     is_abort = True
     self.expect_word('leave')
   else:
     is_abort = False
     self.expect_word('signal')
   (selector, is_async, rest) = self.parse_operator_tail()
   if self.at_word('else'):
     self.expect_word('else')
     default = self.parse_expression(expect_delim)
   else:
     default = None
     self.expect_statement_delimiter(expect_delim)
   return ast.Signal(is_abort, [
     ast.Argument(data._SUBJECT, ast.Literal(None)),
     ast.Argument(data._SELECTOR, ast.Literal(selector)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC))
   ] + rest, default)
Example #12
0
 def parse_if_expression(self, expect_delim):
   self.expect_word('if')
   cond = self.parse_expression(False)
   self.expect_word('then')
   then_part = self.parse_expression(expect_delim)
   if self.at_word('else'):
     self.expect_word('else')
     else_part = self.parse_expression(expect_delim)
   else:
     else_part = ast.Literal(None)
   methods = [
     ast.Lambda.method(then_part, data.Operation.infix('then!')),
     ast.Lambda.method(else_part, data.Operation.infix('else!'))
   ]
   args = [
     ast.Argument(data._SUBJECT, ast.Variable(data.Identifier(-1, data.Path(["core", "if"])))),
     ast.Argument(data._SELECTOR, ast.Literal(Parser._SAUSAGES)),
     ast.Argument(data._TRANSPORT, ast.Literal(data._SYNC)),
     ast.Argument(0, cond),
     ast.Argument(1, ast.Lambda(methods))
   ]
   result = ast.Invocation(args)
   return result
Example #13
0
 def parse_arguments(self, start, end):
   args = []
   if self.at_punctuation(start):
     self.expect_punctuation(start)
     if not self.at_punctuation(end):
       arg = self.parse_argument(0)
       args.append(arg)
       index = 1
       while self.at_punctuation(','):
         self.expect_punctuation(',')
         arg = self.parse_argument(index)
         args.append(arg)
         index += 1
     self.expect_punctuation(end)
   else:
     arg = self.parse_unary_expression()
     args.append(ast.Argument(0, arg))
   return args
Example #14
0
    def parse_function_call(self, first=None):
        expr = ast.FunctionCall(self.cur_tok, [])

        if first != None:
            expr.pattern.append(first)

        # If the current token is a valid arg token, or a keyword
        while self.peek_in(self.arg_tokens) or self.peek_in(
                token.keywords.values()):
            self.next()

            if self.cur_in(token.keywords.values()):
                expr.pattern.append(ast.Identifier(self.cur_tok))
                continue

            arg = lambda val: ast.Argument(self.cur_tok, val)

            handlers = {
                token.ID: lambda: ast.Identifier(self.cur_tok),
                token.PARAM: lambda: arg(ast.Identifier(self.cur_tok))
            }

            found = False
            for k, v in self.prefixes.items():
                if k in handlers.keys():
                    continue

                if k == self.cur_tok.type:
                    expr.pattern.append(arg(v()))
                    found = True

            if not found:
                handler = handlers[self.cur_tok.type]
                expr.pattern.append(handler())

        if len(expr.pattern) == 0:
            self.err("expected at least one item in a pattern")
            return None

        return expr
Example #15
0
    def parse_function_call(self, first=None):
        expr = ast.FunctionCall(self.cur_tok, [])

        if first != None:
            expr.pattern.append(first)

        # If the current token is a valid arg token, or a keyword
        while self.peek_in(arg_tokens) or self.peek_in(
                token.keywords.values()):
            self.next()

            if self.cur_in(token.keywords.values()):
                expr.pattern.append(ast.Identifier(self.cur_tok))
                continue

            arg = lambda val: ast.Argument(self.cur_tok, val)

            handlers = {
                token.ID: lambda: ast.Identifier(self.cur_tok),
                token.LPAREN: lambda: arg(self.parse_grouped_expr()),
                token.NUM: lambda: arg(self.parse_num()),
                token.NULL: lambda: arg(self.parse_null()),
                token.TRUE: lambda: arg(self.parse_bool()),
                token.FALSE: lambda: arg(self.parse_bool()),
                token.STR: lambda: arg(self.parse_string()),
                token.PARAM: lambda: arg(ast.Identifier(self.cur_tok)),
                token.LSQUARE: lambda: arg(self.parse_array_or_object()),
                token.LBRACE: lambda: arg(self.parse_block_literal()),
            }

            handler = handlers[self.cur_tok.type]
            expr.pattern.append(handler())

        if len(expr.pattern) == 0:
            self.err("expected at least one item in a pattern")
            return None

        return expr