Exemple #1
0
def len_function(*args):
    if len(args) != 1:
        return new_error(f"wrong number of arguments. got={len(args)}, want=1")
    if isinstance(args[0], b1u3object.String):
        return b1u3object.Integer(value=len(args[0].value))
    elif isinstance(args[0], b1u3object.Array):
        return b1u3object.Integer(value=len(args[0].elements))
    return new_error(f"argument to `len` not supported, got {args[0].type()}")
 def test_hash_literals(self):
     input = """
     let two = "two";
     {
             "one": 10 -9,
             two: 1 + 1,
             "thr"+ "ee": 6 / 2,
             4: 4,
             true: 5,
             false: 6
     }"""
     evaluated = self.help_test_eval(input)
     self.assertTrue(isinstance(evaluated, b1u3object.Hash),
                     f"Eval didn't return Hash. got={type(evaluated)}")
     expected = {
         b1u3object.String(value="one").hash_key(): 1,
         b1u3object.String(value="two").hash_key(): 2,
         b1u3object.String(value="three").hash_key(): 3,
         b1u3object.Integer(value=4).hash_key(): 4,
         b1u3evaluator.TRUE.hash_key(): 5,
         b1u3evaluator.FALSE.hash_key(): 6
     }
     self.assertEqual(
         len(evaluated.pairs), len(expected),
         f"Hash has wrong num of pairs. got={len(evaluated.pairs)}")
     for expectedKey, expectedValue in expected.items():
         p = evaluated.pairs[expectedKey]
         self.help_test_integer_object(p.value, expectedValue)
Exemple #3
0
def eval_integer_infix_expression(operator, left, right, env):
    if operator == '+':
        return b1u3object.Integer(value=left.value+right.value)
    elif operator == '-':
        return b1u3object.Integer(value=left.value-right.value)
    elif operator == '*':
        return b1u3object.Integer(value=left.value*right.value)
    elif operator == '/':
        return b1u3object.Integer(value=left.value//right.value)
    elif operator == '<':
        return TRUE if left.value < right.value else FALSE
    elif operator == '>':
        return TRUE if left.value > right.value else FALSE
    elif operator == '==':
        return TRUE if left.value == right.value else FALSE
    elif operator == '!=':
        return TRUE if left.value != right.value else FALSE
    else:
        return new_error(f'unknown operator: {left.type()} {operator} {right.type()}')
Exemple #4
0
def b1u3eval(node:b1u3ast.Node, env:Dict[str, b1u3object.Object]) -> b1u3object.Object:
    print(node)
    if isinstance(node, b1u3ast.Program):
        return eval_program(node.statements, env)
    elif isinstance(node, b1u3ast.ExpressionStatement):
        return b1u3eval(node.expression, env)
    elif isinstance(node, b1u3ast.IntegerLiteral):
        return b1u3object.Integer(value=node.value)
    elif isinstance(node, b1u3ast.Boolean):
        if node.value:
            return TRUE
        else:
            return FALSE
    elif isinstance(node, b1u3ast.PrefixExpression):
        # then already ast node has right expression
        right = b1u3eval(node.right, env)
        if is_error(right):
            return right
        return eval_prefix_expression(node.operator, right, env)
    elif isinstance(node, b1u3ast.InfixExpression):
        left = b1u3eval(node.left, env)
        if is_error(left):
            return left
        right = b1u3eval(node.right, env)
        if is_error(right):
            return right
        return eval_infix_expression(node.operator, left, right, env)
    elif isinstance(node, b1u3ast.BlockStatement):
        return eval_block_statement(node, env)
    elif isinstance(node, b1u3ast.IfExpression):
        return eval_if_expression(node, env)
    elif isinstance(node, b1u3ast.ReturnStatement):
        val = b1u3eval(node.return_value, env)
        if is_error(val):
            return val
        return b1u3object.ReturnValue(value=val)
    elif isinstance(node, b1u3ast.LetStatement):
        val = b1u3eval(node.value, env)
        if is_error(val):
            return val
        env[node.name.value] = val
    elif isinstance(node, b1u3ast.Identifier):
        return eval_identifier(node, env)
    elif isinstance(node, b1u3ast.FunctionLiteral):
        params = node.parameters
        body = node.body
        return b1u3object.Function(parameters=params, env=env, body=body)
    elif isinstance(node, b1u3ast.CallExpression):
        if node.function.token_literal() == "quote":
            return quote(node.arguments[0], env)
        function = b1u3eval(node.function, env)
        if is_error(function):
            return function
        args = eval_expressions(node.arguments, env)
        if len(args) == 1 and is_error(args[0]):
            return args[0]
        return apply_function(function, args)
    elif isinstance(node, b1u3ast.StringLiteral):
        return b1u3object.String(value=node.value)
    elif isinstance(node, b1u3ast.ArrayLiteral):
        elements = eval_expressions(node.elements, env)
        if len(elements) == 1 and is_error(elements[0]):
            return [0]
        return b1u3object.Array(elements=elements)
    elif isinstance(node, b1u3ast.IndexExpression):
        left = b1u3eval(node.left, env)
        if is_error(left):
            return left
        index = b1u3eval(node.index, env)
        if is_error(index):
            return index
        return eval_index_expression(left, index)
    elif isinstance(node, b1u3ast.HashLiteral):
        return eval_hash_literal(node, env)
    return NULL
Exemple #5
0
def eval_minus_operator_expression(right, env):
    if right.type() != b1u3object.INTEGER_OBJ:
        return new_error(f'unknown operator: -{right.type()}')
    value = right.value
    return b1u3object.Integer(value=-value)