Ejemplo n.º 1
0
def eval_char_string_infix(op, left, right):
    l = left.value
    r = right.value

    if op == "+": return obj.String(l + r)
    if op == "-": return obj.String([ch for ch in l if ch != r])

    return err("unknown operator: %s %s %s" % (left.type, op, right.type))
Ejemplo n.º 2
0
def eval_infix(op, left, right, ctx):
    if isinstance(left, obj.Collection) and isinstance(right, obj.Collection):
        return eval_collection_infix(op, left, right, ctx)

    # Boolean operators
    if op == "&&": return bool_obj(is_truthy(left) and is_truthy(right))
    if op == "||": return bool_obj(is_truthy(left) or is_truthy(right))
    if op == "==": return bool_obj(left == right)
    if op == "!=": return bool_obj(left != right)

    if op == "?":
        return right if left == NULL else left

    if type(left) == obj.Number and type(right) == obj.Number:
        return eval_number_infix(op, left, right)

    if (type(left) == obj.Char and type(right) == obj.Char
            or type(left) == obj.String and type(right) == obj.Char
            or type(left) == obj.Char and type(right) == obj.String):
        return eval_char_string_infix(op, left, right)

    if (type(left) == obj.Char and type(right) == obj.Number):
        return obj.String(left.value * math.floor(right.value))

    if isinstance(left, obj.Collection) and type(right) == obj.Number:
        result = []
        elems = left.get_elements()
        n = math.floor(right.value)

        for _ in range(n):
            result += elems[:]

        return type(left)(result)

    return err("unknown operator: %s %s %s" % (left.type, op, right.type))
Ejemplo n.º 3
0
def format_string_with_args(args, context):
    fmt = args["format"].value
    items = tuple(args["args"].get_elements())

    try:
        return obj.String(fmt % items)
    except TypeError:
        return err("Wrong number of arguments to format `%s`" % fmt)
Ejemplo n.º 4
0
def printf_format_with_args(args, context):
    fmt = args["format"].value
    items = tuple(args["args"].get_elements())

    try:
        print(obj.String(fmt % items))
    except TypeError:
        return err("Wrong number of arguments to format `%s`" % fmt,
                   "TypeError")

    return NULL
Ejemplo n.º 5
0
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.Char: return obj.Char(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.Object:
        keys = eval_exprs(node.pairs.keys(), ctx)
        if len(keys) == 1 and is_err(keys[0]):
            return keys[0]

        values = eval_exprs(node.pairs.values(), ctx)
        if len(values) == 1 and is_err(values[0]):
            return values[0]

        return obj.Object(list(zip(keys, values)))

    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:
        right = evaluate(node.value, ctx)
        return right if is_err(right) else eval_assign(node.name, right, ctx)

    if t == ast.DeclareExpression:
        right = evaluate(node.value, ctx)
        return right if is_err(right) else eval_declare(node.name, right, ctx)

    return err("evaluation for %s not yet implemented" % t)
Ejemplo n.º 6
0
def input_with_prompt_prompt(args, context):
    try:
        return obj.String(input(args["prompt"]))
    except (KeyboardInterrupt, EOFError):
        return NULL
Ejemplo n.º 7
0
def _input(args, context):
    try:
        return obj.String(input())
    except (KeyboardInterrupt, EOFError):
        return NULL