Пример #1
0
def eval(node: ast.Node, env: object.Environment):
    if type(node) is ast.Program:
        return eval_program(node.statements, env)
    elif type(node) is ast.ExpressionStatement:
        return eval(node.expression, env)
    elif type(node) is ast.LetStatement:
        val = eval(node.value, env)
        if is_error(val):
            return val
        env.set(node.name.value, val)
    elif type(node) is ast.Identifier:
        return eval_identifier(node, env)
    elif type(node) is ast.StringLiteral:
        return object.String(value=node.value)
    elif type(node) is ast.FunctionLiteral:
        parameters = node.parameters
        body = node.body
        return object.Function(parameters=parameters, body=body, env=env)
    elif type(node) is ast.CallExpression:
        fun = eval(node.function, env)
        if is_error(fun):
            return fun
        args = eval_expressions(node.arguments, env)
        if len(args) == 1 and is_error(args[0]):
            return args[0]
        return apply_function(fun, args)
    elif type(node) is ast.PrefixExpression:
        right = eval(node.right, env)
        if is_error(right):
            return right
        return eval_prefix_expression(node.operator, right)
    elif type(node) is 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 type(node) is ast.IntegerLiteral:
        return object.Integer(value=node.value)
    elif type(node) is ast.BlockStatement:
        return eval_block_statements(node.statements, env)
    elif type(node) is ast.IfExpression:
        return eval_if_expression(node, env)
    elif type(node) is ast.ReturnStatement:
        val = eval(node.return_value, env)
        return object.ReturnValue(value=val)
    elif type(node) is ast.Boolean:
        return object.TRUE if node.value is True else object.FALSE
Пример #2
0
def addMacro(stmt: ast.Statement, env: object.Environment) -> None:
    letStatement = cast(ast.LetStatement, stmt)
    macroLiteral = cast(ast.MacroLiteral, letStatement.Value)
    macro = object.Macro(
        Parameters=macroLiteral.Parameters,
        Env=env,
        Body=macroLiteral.Body,
    )
    env.Set(letStatement.Name.Value, macro)
Пример #3
0
def eval_identifier(node: ast.Identifier, env: object.Environment):
    val = env.get(node.value)
    if val is not None:
        return val

    if node.value in builtins:
        return builtins[node.value]

    return object.Error("identifier not found: {}".format(node.token.literal))
Пример #4
0
def eval_identifier(node: ast.Identifier,
                    env: object.Environment) -> object.Object:
    val, ok = env.get(node.value)
    if ok:
        return val

    if node.value in builtins:
        return builtins[node.value]

    return new_error('identifier not found: ' + node.value)
Пример #5
0
def evalIdentifier(node: ast.Identifier,
                   env: object.Environment) -> Optional[object.Object]:
    val = env.Get(node.Value)
    if val:
        return val

    builtin = builtins.get(node.Value)
    if builtin:
        return builtin

    return newError('identifier not found: ' + node.Value, tuple())
Пример #6
0
def isMacroCall(exp: ast.CallExpression,
                env: object.Environment) -> Optional[object.Macro]:
    if type(exp.Function) != ast.Identifier:
        return None
    identifier = cast(ast.Identifier, exp.Function)

    obj = env.Get(identifier.Value)
    if not obj:
        return None

    if type(obj) != object.Macro:
        return None
    macro = cast(object.Macro, obj)

    return macro
Пример #7
0
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: 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