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)
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)
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)
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)
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)
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)
def create_list(interpreter, values): return Value(Value.LIST, list(values))
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)
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)
def list_tail(interpreter, values): l = _single_param_list_func(values, 'tail') return Value(Value.LIST, l[1:])
def list_head(interpreter, values): l = _single_param_list_func(values, 'head') return Value(Value.LIST, l[:-1])
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')