<commit_before>import math

import obj
import ast
import context
from evaluator import NULL, TRUE, FALSE, evaluate, err, is_truthy


class Builtin(object):
    builtins = []

    """a builtin function"""
    def __init__(self, pattern, fn):
        self.pattern = pattern.split() # e.g. ["print", "$obj"]
        self.fn = fn                   # fn(args, context) where args is a dictionary

        Builtin.builtins.append(self)


def pattern(pattern):
    def pattern_decorator(fn):
        setattr(fn, "pattern", pattern)
        return fn
    
    return pattern_decorator

def builtin(fn):
    Builtin(getattr(fn, "pattern"), fn)
    return fn

def arg(name, expected_type):
    def arg_decorator(fn):     
        def new_fn(args, context):            
            if not isinstance(args[name], expected_type):                
                return err("the $%s parameter must be of type %s, not %s" % (
                    name,
                    expected_type.t,
                    args[name].type
                ))

            return fn(args, context)
        
        return new_fn

    return arg_decorator


## Builtin definitions ##

@builtin
@pattern("round $n")
@arg("n", obj.Number)
def round_n(args, context):
    n = args["n"]
    
    return obj.Number(round(n.value))

@builtin
@pattern("print $obj")
def print_obj(args, context):
    print(args["obj"])
    return NULL

@builtin
@pattern("print $obj without newline")
def print_obj_without_newline(args, context):
    print(args["obj"], end="")
    return NULL

@builtin
@pattern("input")
def _input(args, context):
    try:
        return obj.String(input())
    except (KeyboardInterrupt, EOFError):
        return NULL

@builtin
@pattern("input with prompt $prompt")
def input_with_prompt_prompt(args, context):
    try:
        return obj.String(input(args["prompt"]))
    except (KeyboardInterrupt, EOFError):
        return NULL

def _run_block(block, args, context):
    params = [param.value for param in block.params]
    args_dict = dict(zip(params, args))
    ctx = context.enclose_with_args(args_dict)
    return evaluate(block.body, ctx)

@builtin
@pattern("do $block")
@arg("block", obj.Block)
def do_block(args, context):
    block = args["block"]

    if type(block) != obj.Block:<commit_msg>Add the `throw $tag $msg` builtin<commit_after>import math

import obj
import ast
import context
from evaluator import NULL, TRUE, FALSE, evaluate, err, is_truthy


class Builtin(object):
    builtins = []

    """a builtin function"""
    def __init__(self, pattern, fn):
        self.pattern = pattern.split() # e.g. ["print", "$obj"]
        self.fn = fn                   # fn(args, context) where args is a dictionary

        Builtin.builtins.append(self)


def pattern(pattern):
    def pattern_decorator(fn):
        setattr(fn, "pattern", pattern)
        return fn
    
    return pattern_decorator

def builtin(fn):
    Builtin(getattr(fn, "pattern"), fn)
    return fn

def arg(name, expected_type):
    def arg_decorator(fn):     
        def new_fn(args, context):            
            if not isinstance(args[name], expected_type):                
                return err("the $%s parameter must be of type %s, not %s" % (
                    name,
                    expected_type.t,
                    args[name].type
                ))

            return fn(args, context)
        
        return new_fn

    return arg_decorator


## Builtin definitions ##

@builtin
@pattern("round $n")
@arg("n", obj.Number)
def round_n(args, context):
    n = args["n"]
    
    return obj.Number(round(n.value))

@builtin
@pattern("print $obj")
def print_obj(args, context):
    print(args["obj"])
    return NULL

@builtin
@pattern("print $obj without newline")
def print_obj_without_newline(args, context):
    print(args["obj"], end="")
    return NULL

@builtin
@pattern("input")
def _input(args, context):
    try:
        return obj.String(input())
    except (KeyboardInterrupt, EOFError):
        return NULL

@builtin
@pattern("input with prompt $prompt")
def input_with_prompt_prompt(args, context):
    try:
        return obj.String(input(args["prompt"]))
    except (KeyboardInterrupt, EOFError):
        return NULL

@builtin
@pattern("throw $tag $message")
@arg("tag", obj.String)
@arg("message", obj.String)
def throw_tag_message(args, context):
    return err(args["message"], args["tag"])

def _run_block(block, args, context):
    params = [param.value for param in block.params]
    args_dict = dict(zip(params, args))
    ctx = context.enclose_with_args(args_dict)
    return evaluate(block.body, ctx)

@builtin
@pattern("do $block")
@arg("block", obj.Block)
def do_block(args, context):
    block = args["block"]

    if type(block) != obj.Block:
{'fraction_non_alphanumeric': 0.12649465072372562, 'fraction_numerical': 0.0, 'mean_word_length': 2.7691699604743083, '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': '1412697', 'n_tokens_mistral': 1482, 'n_tokens_neox': 1460, 'n_words': 394}