Exemplo n.º 1
0
def is_truthy(obj: objects.Object) -> bool:
    if obj is objects.Null():
        return False
    elif obj is objects.Boolean(True):
        return True
    elif obj is objects.Boolean(False):
        return False
    return True
Exemplo n.º 2
0
def evaluate_string_infix_expression(operator: str, left: objects.Object,
                                     right: objects.Object) -> objects.Object:
    if operator == "+":
        return objects.String(left.value + right.value)
    elif operator == "==":
        return objects.Boolean(left.value == right.value)
    elif operator == "!=":
        return objects.Boolean(left.value != right.value)

    return new_error(
        f"unknown operator: {left.object_type().value} {operator} {right.object_type().value}"
    )
Exemplo n.º 3
0
def evaluate_bang_operator_expression(right: objects.Object) -> objects.Object:
    if right is objects.Boolean(True):
        return objects.Boolean(False)
    elif right is objects.Boolean(False):
        return objects.Boolean(True)
    elif right is objects.Null():
        return objects.Boolean(True)
    else:
        return objects.Boolean(False)
Exemplo n.º 4
0
def native_bool_to_boolean_object(input_: bool) -> objects.Boolean:
    if input_:
        return objects.Boolean(True)
    return objects.Boolean(False)
Exemplo n.º 5
0
def evaluate(node: ast.Node, env: objects.Environment) -> objects.Object:
    # print(f"EVALUATING: node:<{node}>, type: <{type(node)}>")
    if isinstance(node, ast.Program):
        return evaluate_program(node, env)
    elif isinstance(node, ast.ExpressionStatement):
        return evaluate(node.expression, env)
    elif isinstance(node, ast.BlockStatement):
        return evaluate_block_statement(node, env)
    elif isinstance(node, ast.ReturnStatement):
        value = evaluate(node.return_value, env)
        if is_error(value):
            return value
        return objects.ReturnValue(value)
    elif isinstance(node, ast.LetStatement):
        val = evaluate(node.value, env)
        if is_error(val):
            return val
        env.set(node.name.value, val)
    elif isinstance(node, ast.IntegerLiteral):
        return objects.Integer(node.value)
    elif isinstance(node, ast.StringLiteral):
        return objects.String(node.value)
    elif isinstance(node, ast.ArrayLiteral):
        elements = evaluate_expressions(node.elements, env)
        if len(elements) == 1 and is_error(elements[0]):
            return elements[0]
        return objects.Array(elements)
    elif isinstance(node, ast.HashLiteral):
        return evaluate_hash_literal(node, env)
    elif isinstance(node, ast.Boolean):
        if node.value:
            return objects.Boolean(True)
        return objects.Boolean(False)
    elif isinstance(node, ast.PrefixExpression):
        right = evaluate(node.right, env)
        if is_error(right):
            return right
        return evaluate_prefix_expression(node.operator, right)
    elif isinstance(node, ast.InfixExpression):
        left = evaluate(node.left, env)
        if is_error(left):
            return left
        right = evaluate(node.right, env)
        if is_error(right):
            return right
        return evaluate_infix_expression(node.operator, left, right)
    elif isinstance(node, ast.IfExpression):
        return evaluate_if_expression(node, env)
    elif isinstance(node, ast.Identifier):
        return evaluate_identifier(node, env)
    elif isinstance(node, ast.FunctionLiteral):
        params = node.parameters
        body = node.body
        return objects.Function(params, body, env)
    elif isinstance(node, ast.CallExpression):
        function = evaluate(node.function, env)
        if is_error(function):
            return function
        args = evaluate_expressions(node.arguments, env)
        if len(args) == 1 and is_error(args[0]):
            return args[0]
        return apply_function(function, args)
    elif isinstance(node, ast.IndexExpression):
        left = evaluate(node.left, env)
        if is_error(left):
            return left
        index = evaluate(node.index, env)
        if is_error(index):
            return index
        return evaluate_index_expression(left, index)
    elif isinstance(node, ast.ImportExpression):
        return evaluate_import_expression(node, env)
    elif isinstance(node, ast.WhileStatement):
        return evaluate_while_statement(node, env)
    return None