コード例 #1
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def boolean_not(interpreter, values):
    if len(values) == 0:
        raise NotEnoughParametersException('not requires one parameter')
    if len(values) > 1:
        raise TooManyParametersException('not requires one parameter')
    boolean = values[0]
    if boolean.type != Value.BOOLEAN:
        raise UnsupportedParameterType('parameter of not must be a boolean')
    return Value(Value.BOOLEAN, not boolean.value)
コード例 #2
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def plus(interpreter, values):
    if len(values) == 0:
        raise NotEnoughParametersException('+ requires at least one parameter')
    plus_sum = 0
    for value in values:
        if not value.type == Value.INTEGER:
            raise UnsupportedParameterType(
                '+ operator: unsupported operand: {}'.format(value))
        plus_sum += value.value
    return Value(Value.INTEGER, plus_sum)
コード例 #3
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def boolean_or(interpreter, values):
    if len(values) < 2:
        raise NotEnoughParametersException(
            'or requires at least two parameters')
    if values[0].type != Value.BOOLEAN:
        raise UnsupportedParameterType('parameters of or must be booleans')
    boolean = values[0].value
    for value in values[1:]:
        if not value.type == Value.BOOLEAN:
            raise UnsupportedParameterType('parameters of or must be booleans')
        boolean = boolean or value.value
    return Value(Value.BOOLEAN, boolean)
コード例 #4
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def div(interpreter, values):
    if len(values) == 0:
        raise NotEnoughParametersException('/ requires at least one parameter')
    if values[0].type != Value.INTEGER:
        raise UnsupportedParameterType(
            '- operator: unsupported operand: {}'.format(values[0].value))
    div_sum = values[0].value
    for value in values[1:]:
        if not value.type == Value.INTEGER:
            raise UnsupportedParameterType(
                '/ operator: unsupported operand: {}'.format(value))
        div_sum //= value.value
    return Value(Value.INTEGER, div_sum)
コード例 #5
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def minus(interpreter, values):
    if len(values) == 0:
        raise NotEnoughParametersException('- requires at least one parameter')
    if values[0].type != Value.INTEGER:
        raise UnsupportedParameterType(
            '- operator: unsupported operand: {}'.format(values[0].value))
    minus_sum = values[0].value
    if len(values) == 1:
        minus_sum = -minus_sum
    else:
        for value in values[1:]:
            if not value.type == Value.INTEGER:
                raise UnsupportedParameterType(
                    '- operator: unsupported operand: {}'.format(value))
            minus_sum -= value.value
    return Value(Value.INTEGER, minus_sum)
コード例 #6
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def list_map(interpreter, values):
    if not len(values) == 2:
        raise NotEnoughParametersException(
            'map required two params: <function> <list>')
    func, list_value = values
    if func.type != Value.FUNCTION:
        raise UnsupportedParameterType(
            'First parameter of map must be a function')
    if list_value.type != Value.LIST:
        raise UnsupportedParameterType(
            'Second parameter of map must be a list')

    ret = []
    for value in list_value.value:
        ret.append(interpreter.function(func.value, [value], {}))

    return Value(Value.LIST, ret)
コード例 #7
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def create_list(interpreter, values):
    return Value(Value.LIST, list(values))
コード例 #8
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def bigger_or_equal_than(interpreter, values):
    value1, value2 = _two_param_integer_func(values, '<')
    if value1 >= value2:
        return Value(Value.BOOLEAN, True)
    else:
        return Value(Value.BOOLEAN, False)
コード例 #9
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def smaller_than(interpreter, values):
    value1, value2 = _two_param_integer_func(values, '<')
    if value1 < value2:
        return Value(Value.BOOLEAN, True)
    else:
        return Value(Value.BOOLEAN, False)
コード例 #10
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def list_tail(interpreter, values):
    l = _single_param_list_func(values, 'tail')
    return Value(Value.LIST, l[1:])
コード例 #11
0
ファイル: interpreter_builtins.py プロジェクト: fotcorn/lisp
def list_head(interpreter, values):
    l = _single_param_list_func(values, 'head')
    return Value(Value.LIST, l[:-1])
コード例 #12
0
ファイル: interpreter.py プロジェクト: fotcorn/lisp
    def evaluate(self, value, variable_context):
        if isinstance(value, Number):
            return Value(Value.INTEGER, value.value)
        elif isinstance(value, String):
            return Value(Value.STRING, value.value)
        elif isinstance(value, Function):
            return Value(Value.FUNCTION, value, variable_context)
        elif isinstance(value, Identifier):
            if value.value == 'true':
                return Value(Value.BOOLEAN, True)
            elif value.value == 'false':
                return Value(Value.BOOLEAN, False)
            elif value.value in variable_context:
                return variable_context[value.value]
            elif value.value in self.variables:
                return self.variables[value.value]
            else:
                raise InterpreterException('Unknown variable {}'.format(
                    value.value))
        elif isinstance(value, Call):
            operator = value.expressions[0]

            if isinstance(operator, Function):
                values = []
                for param in value.expressions[1:]:
                    values.append(self.evaluate(param, variable_context))
                return self.function(operator, values, variable_context)

            if operator.value == 'def':
                if not len(value.expressions) == 3:
                    raise InterpreterException(
                        'def takes exactly two arguments')
                if not isinstance(value.expressions[1], Identifier):
                    raise InterpreterException(
                        'The first argument of def must be an identifier')
                variable_value = self.evaluate(value.expressions[2],
                                               variable_context)
                variable_name = value.expressions[1].value
                self.variables[variable_name] = variable_value
                return

            values = []
            for param in value.expressions[1:]:
                values.append(self.evaluate(param, variable_context))

            if isinstance(operator, Identifier):
                if operator.value in self.builtins:
                    builtin = self.builtins[operator.value]
                    return builtin(self, values)
                elif operator.value in self.variables:
                    variable = self.variables[operator.value]
                    if variable.type != Value.FUNCTION:
                        raise InterpreterException(
                            'Trying to call non-function value: {}'.format(
                                variable))
                    func_context = variable_context.copy()
                    func_context.update(variable.variable_context)
                    return self.function(variable.value, values, func_context)
                else:
                    raise InterpreterException(
                        'Trying to call unknown function: {}'.format(
                            operator.value))
            else:
                raise InterpreterException(
                    'Trying to execute non-function as function')