コード例 #1
0
def push(*args: List[object.Object]) -> object.Object:
    if len(args) != 2:
        return evaluator.new_error('wrong number of arguments. got={}, want=2', len(args))
    if args[0].type() != object.ARRAY_OBJ:
        return evaluator.new_error('argument to `push` must be ARRAY, got {}'.format(args[0].type()))

    arr = args[0]

    new_elements = copy.deepcopy(arr.elements)
    new_elements.append(args[1])

    return object.Array(new_elements)
コード例 #2
0
def _builtin_push(args: List[monkey_obj.Object]) -> monkey_obj.Object:
    if len(args) != 2:
        return monkey_obj.Error(
            f"wrong number of arguments. got={len(args)}, want=2")

    arr, obj = args

    if not isinstance(arr, monkey_obj.Array):
        return monkey_obj.Error(
            f"argumetn to `push` must be ARRAY, got {type(arr)}")

    return monkey_obj.Array(arr.elements + [obj])
コード例 #3
0
def rest(*args: List[object.Object]) -> object.Object:
    if len(args) != 1:
        return evaluator.new_error('wrong number of arguments. got={}, want=1', len(args))
    if args[0].type() != object.ARRAY_OBJ:
        return evaluator.new_error('argument to `rest` must be ARRAY, got {}'.format(args[0].type()))

    arr = args[0]
    length = len(arr.elements)
    if length > 0:
        new_elements = copy.deepcopy(arr.elements[1:length])
        return object.Array(new_elements)

    return evaluator.NULL
コード例 #4
0
def _builtin_rest(args: List[monkey_obj.Object]) -> monkey_obj.Object:
    if len(args) != 1:
        return monkey_obj.Error(
            f"wrong number of arguments. got={len(args)}, want=1")

    item = next(iter(args))

    if not isinstance(item, monkey_obj.Array):
        return monkey_obj.Error(
            f"argumetn to `rest` must be ARRAY, got {type(item)}")

    if len(item.elements) > 0:
        return monkey_obj.Array(item.elements[1:])

    return monkey_obj.NULL
コード例 #5
0
ファイル: evaluator.py プロジェクト: rokujyouhitoma/monkey-py
def builtin_push(args: List[object.Object]) -> object.Object:
    if len(args) != 2:
        return newError('wrong number of arguments. got=%s, want=2',
                        (len(args), ))

    arg = args[0]
    if arg.Type.TypeName != object.ARRAY_OBJ:
        return newError('argument to `push` must be ARRAY, got %s',
                        (args[0].Type.TypeName, ))

    arr = cast(object.Array, arg)

    newElements = copy.deepcopy(arr.Elements)
    newElements.append(args[1])

    return object.Array(Elements=newElements)
コード例 #6
0
ファイル: evaluator.py プロジェクト: rokujyouhitoma/monkey-py
def builtin_rest(args: List[object.Object]) -> object.Object:
    if len(args) != 1:
        return newError('wrong number of arguments. got=%s, want=1',
                        (len(args), ))

    arg = args[0]
    if arg.Type.TypeName != object.ARRAY_OBJ:
        return newError('argument to `rest` must be ARRAY, got %s',
                        (args[0].Type.TypeName, ))

    arr = cast(object.Array, arg)
    length = len(arr.Elements)
    if length > 0:
        newElements = copy.deepcopy(arr.Elements[1:])
        return object.Array(Elements=newElements)

    return NULL
コード例 #7
0
ファイル: evaluator.py プロジェクト: rokujyouhitoma/monkey-py
def Eval(node: Any, env: object.Environment) -> Optional[object.Object]:
    if type(node) == ast.Program:
        return evalProgram(node, env)
    elif type(node) == ast.ExpressionStatement:
        return Eval(node.ExpressionValue, env)
    elif type(node) == ast.IntegerLiteral:
        return object.Integer(Value=node.Value)
    elif type(node) == ast.Boolean:
        return nativeBoolToBooleanObject(node.Value)
    elif type(node) == ast.PrefixExpression:
        right = Eval(node.Right, env)
        if right:
            if isError(right):
                return right
            return evalPrefixExpression(node.Operator, right)
        else:
            return None
    elif type(node) == ast.InfixExpression:
        left = Eval(node.Left, env)
        if not left:
            return None
        if isError(left):
            return left
        right = Eval(node.Right, env)
        if not right:
            return None
        if isError(right):
            return right
        evaluated = evalInfixExpression(node.Operator, left, right)
        return evaluated
    elif type(node) == ast.BlockStatement:
        return evalBlockStatement(node, env)
    elif type(node) == ast.IfExpression:
        return evalIfExpression(node, env)
    elif type(node) == ast.ReturnStatement:
        val = Eval(node.ReturnValue, env)
        if val:
            if isError(val):
                return val
            return object.ReturnValue(Value=val)
        else:
            return None
    elif type(node) == ast.LetStatement:
        val = Eval(node.Value, env)
        if val:
            if isError(val):
                return val
            env.Set(node.Name.Value, val)
        else:
            return None
    elif type(node) == ast.Identifier:
        return evalIdentifier(node, env)
    elif type(node) == ast.FunctionLiteral:
        params = node.Parameters
        body = node.Body
        return object.Function(Parameters=params, Env=env, Body=body)
    elif type(node) == ast.CallExpression:
        if node.Function.TokenLiteral() == 'quote':
            return quote(node.Arguments[0], env)
        function = Eval(node.Function, env)
        if function:
            if isError(function):
                return function
        args = evalExpressions(node.Arguments, env)
        if len(args) == 1 and isError(args[0]):
            return args[0]
        if not function:
            return None
        return applyFunction(function, args)
    elif type(node) == ast.StringLiteral:
        return object.String(Value=node.Value)
    elif type(node) == ast.ArrayLiteral:
        elements = evalExpressions(node.Elements, env)
        if len(elements) == 1 and isError(elements[0]):
            return elements[0]
        return object.Array(Elements=elements)
    elif type(node) == ast.IndexExpression:
        left = Eval(node.Left, env)
        if not left:
            return None
        if isError(left):
            return left
        index = Eval(node.Index, env)
        if not index:
            return None
        if isError(index):
            return index
        return evalIndexExpression(left, index)
    elif type(node) == ast.HashLiteral:
        return evalHashLiteral(node, env)
    return None
コード例 #8
0
def Eval(node: ast.Node, env) -> monkey_obj.Object:

    if isinstance(node, ast.Program):
        return eval_program(node.statements, env)

    elif isinstance(node, ast.HashLiteral):
        return eval_hash_literal(node, env)

    elif isinstance(node, ast.ArrayLiteral):
        elements = [Eval(e, env) for e in node.elements]
        if len(elements) == 1 and isinstance(elements[0], monkey_obj.Error):
            return elements[0]
        return monkey_obj.Array(elements=elements)

    elif isinstance(node, ast.IndexExpression):
        left = Eval(node.left, env)
        if left is not None and isinstance(left, monkey_obj.Error):
            return left

        index = Eval(node.index, env)
        if index is not None and isinstance(index, monkey_obj.Error):
            return index

        return eval_index_expression(left, index)

    elif isinstance(node, ast.StringLiteral):
        return monkey_obj.String(value=node.value)

    elif isinstance(node, ast.CallExpression):
        function = Eval(node.function, env)
        if function is not None and isinstance(function, monkey_obj.Error):
            return function

        args = [Eval(e, env) for e in node.arguments]
        for arg in args:
            if arg is not None and isinstance(function, monkey_obj.Error):
                return arg
        return apply_function(function, args)

    elif isinstance(node, ast.FunctionLiteral):
        params = node.params
        body = node.body
        return monkey_obj.Function(params, env, body)

    elif isinstance(node, ast.BlockStatement):
        return eval_block_statements(node.statements, env)

    elif isinstance(node, ast.IfExpression):
        return eval_if_expression(node, env)

    elif isinstance(node, ast.Identifier):
        return eval_identifier(node, env)

    elif isinstance(node, ast.LetStatement):
        val = Eval(node.value, env)
        if val is not None and isinstance(val, monkey_obj.Error):
            return val
        env[node.name.value] = val
        return monkey_obj.NULL

    elif isinstance(node, ast.ReturnStatement):
        val = Eval(node.value, env)
        if val is not None and isinstance(val, monkey_obj.Error):
            return val
        return monkey_obj.ReturnValue(value=val)

    elif isinstance(node, ast.ExpressionStatement):
        return Eval(node.expression, env)

    elif isinstance(node, ast.Boolean):
        return native_bool_to_boolean_object(node.value)

    elif isinstance(node, ast.IntegerLiteral):
        return monkey_obj.Integer(value=node.value)

    elif isinstance(node, ast.PrefixExpression):
        right = Eval(node.right, env)
        if right is not None and isinstance(right, monkey_obj.Error):
            return val
        return eval_prefix_expression(node.operator, right)

    elif isinstance(node, ast.InfixExpression):
        left = Eval(node.left, env)
        if left is not None and isinstance(left, monkey_obj.Error):
            return left
        right = Eval(node.right, env)
        if right is not None and isinstance(right, monkey_obj.Error):
            return val
        return eval_infix_expression(node.operator, left, right)

    else:
        raise NotImplementedError(str(node), node.token_literal())
コード例 #9
0
def eval(node: ast.Node,
         env: object.Environment) -> Union[object.Object, None]:

    # Statements

    if issubclass(node.__class__, ast.Program):
        return eval_program(node, env)

    elif issubclass(node.__class__, ast.BlockStatement):
        return eval_block_statement(node, env)

    elif issubclass(node.__class__, ast.ExpressionStatement):
        return eval(node.expression, env)

    elif issubclass(node.__class__, ast.ReturnStatement):
        val = eval(node.return_value, env)
        if is_error(val):
            return val
        return object.ReturnValue(val)

    elif issubclass(node.__class__, ast.LetStatement):
        val = eval(node.value, env)
        if is_error(val):
            return val
        env.set(node.name.value, val)

    # Expressions

    elif issubclass(node.__class__, ast.IntegerLiteral):
        return object.Integer(node.value)

    elif issubclass(node.__class__, ast.StringLiteral):
        return object.String(node.value)

    elif issubclass(node.__class__, ast.Boolean):
        return native_bool_to_boolean_object(node.value)

    elif issubclass(node.__class__, ast.PrefixExpression):
        right = eval(node.right, env)
        if is_error(right):
            return right
        return eval_prefix_expression(node.operator, right)

    elif issubclass(node.__class__, ast.InfixExpression):
        left = eval(node.left, env)
        if is_error(left):
            return left

        right = eval(node.right, env)
        if is_error(right):
            return right

        return eval_infix_expression(node.operator, left, right)

    elif issubclass(node.__class__, ast.IfExpression):
        return eval_if_expression(node, env)

    elif issubclass(node.__class__, ast.Identifier):
        return eval_identifier(node, env)

    elif issubclass(node.__class__, ast.FunctionLiteral):
        params = node.parameters
        body = node.body
        return object.Function(params, body, env)

    elif issubclass(node.__class__, ast.CallExpression):
        function = eval(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 issubclass(node.__class__, ast.ArrayLiteral):
        elements = eval_expressions(node.elements, env)
        if len(elements) == 1 and is_error(elements[0]):
            return elements[0]
        return object.Array(elements)

    elif issubclass(node.__class__, ast.IndexExpression):
        left = eval(node.left, env)
        if is_error(left):
            return left
        index = eval(node.index, env)
        if is_error(index):
            return index
        return eval_index_expression(left, index)

    elif issubclass(node.__class__, ast.HashLiteral):
        return eval_hash_literal(node, env)

    return None