<commit_before>import obj
import ast

NULL  = obj.Null()
TRUE  = obj.Boolean(True)
FALSE = obj.Boolean(False)

NEXT  = obj.Next()
BREAK = obj.Break()

def evaluate(node, ctx):
    t = type(node)
    
    # Constructs
    if t == ast.Program:              return eval_program(node, ctx)
    if t == ast.BlockStatement:       return eval_block_stmt(node, ctx)
    if t == ast.ExpressionStatement:  return evaluate(node.expr, ctx)
    if t == ast.IfExpression:         return eval_if(node, ctx)
    if t == ast.WhileLoop:            return eval_while_loop(node, ctx)
    if t == ast.ForLoop:              return eval_for_loop(node, ctx)
    
    # Literals
    if t == ast.Null:                 return NULL
    if t == ast.Number:               return obj.Number(node.value)
    if t == ast.String:               return obj.String(node.value)
    if t == ast.Boolean:              return bool_obj(node.value)
    if t == ast.Identifier:           return eval_id(node, ctx)
    if t == ast.BlockLiteral:         return eval_block(node, ctx)
    
    if t == ast.NextStatement:        return NEXT
    if t == ast.BreakStatement:       return BREAK
    
    # Functions
    if t == ast.FunctionDefinition:   return eval_function_def(node, ctx)
    if t == ast.FunctionCall:         return eval_function_call(node, ctx)
    
    if t == ast.Array:
        elements = eval_exprs(node.elements, ctx)
        
        if len(elements) == 1 and is_err(elements[0]):
            return elements[0]
        
        return obj.Array(elements)
        
    if t == ast.Tuple:
        elements = eval_exprs(node.value, ctx)
        
        if len(elements) == 1 and is_err(elements[0]):
            return elements[0]
            
        return obj.Tuple(elements)
    
    # More complex nodes
    if t == ast.ReturnStatement:
        if node.value == None:
            return NULL
        
        val = evaluate(node.value, ctx)
        return val if is_err(val) else obj.ReturnValue(val)
    
    if t == ast.PrefixExpression:
        right = evaluate(node.right, ctx)
        return right if is_err(right) else eval_prefix(node.operator, right)
    
    if t == ast.InfixExpression:
        left = evaluate(node.left, ctx)
        if is_err(left): return left
        
        right = evaluate(node.right, ctx)
        if is_err(right): return right
        
        return eval_infix(node.operator, left, right, ctx)
    
    if t == ast.AssignExpression:<commit_msg>Make a return statement without a value still work<commit_after>import obj
import ast

NULL  = obj.Null()
TRUE  = obj.Boolean(True)
FALSE = obj.Boolean(False)

NEXT  = obj.Next()
BREAK = obj.Break()

def evaluate(node, ctx):
    t = type(node)
    
    # Constructs
    if t == ast.Program:              return eval_program(node, ctx)
    if t == ast.BlockStatement:       return eval_block_stmt(node, ctx)
    if t == ast.ExpressionStatement:  return evaluate(node.expr, ctx)
    if t == ast.IfExpression:         return eval_if(node, ctx)
    if t == ast.WhileLoop:            return eval_while_loop(node, ctx)
    if t == ast.ForLoop:              return eval_for_loop(node, ctx)
    
    # Literals
    if t == ast.Null:                 return NULL
    if t == ast.Number:               return obj.Number(node.value)
    if t == ast.String:               return obj.String(node.value)
    if t == ast.Boolean:              return bool_obj(node.value)
    if t == ast.Identifier:           return eval_id(node, ctx)
    if t == ast.BlockLiteral:         return eval_block(node, ctx)
    
    if t == ast.NextStatement:        return NEXT
    if t == ast.BreakStatement:       return BREAK
    
    # Functions
    if t == ast.FunctionDefinition:   return eval_function_def(node, ctx)
    if t == ast.FunctionCall:         return eval_function_call(node, ctx)
    
    if t == ast.Array:
        elements = eval_exprs(node.elements, ctx)
        
        if len(elements) == 1 and is_err(elements[0]):
            return elements[0]
        
        return obj.Array(elements)
        
    if t == ast.Tuple:
        elements = eval_exprs(node.value, ctx)
        
        if len(elements) == 1 and is_err(elements[0]):
            return elements[0]
            
        return obj.Tuple(elements)
    
    # More complex nodes
    if t == ast.ReturnStatement:
        if node.value == None:
            return obj.ReturnValue(NULL)
        
        val = evaluate(node.value, ctx)
        return val if is_err(val) else obj.ReturnValue(val)
    
    if t == ast.PrefixExpression:
        right = evaluate(node.right, ctx)
        return right if is_err(right) else eval_prefix(node.operator, right)
    
    if t == ast.InfixExpression:
        left = evaluate(node.left, ctx)
        if is_err(left): return left
        
        right = evaluate(node.right, ctx)
        if is_err(right): return right
        
        return eval_infix(node.operator, left, right, ctx)
    
    if t == ast.AssignExpression:
{'fraction_non_alphanumeric': 0.10072376357056695, 'fraction_numerical': 0.0024125452352231603, 'mean_word_length': 1.964839094159714, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '169580', 'n_tokens_mistral': 1495, 'n_tokens_neox': 1480, 'n_words': 407}