Ejemplo n.º 1
0
 def _eval_define(self, node: obj.Cell):
     try:
         _, sym, expr = node
     except ValueError:
         raise InvalidFormError(
             "define form should consist of 2 elements"
             " first one being a symbol and the second one being"
             " an assigned expression")
     if not isinstance(sym, obj.Symbol):
         raise InvalidFormError(
             "first argument to the define form should be a symbol")
     self._current_env[sym] = self.eval(expr)
Ejemplo n.º 2
0
 def _eval_lambda(self, node: obj.Cell):
     try:
         _, args, body = node
     except ValueError:
         raise InvalidFormError(
             "lambda form should consist of arguments and a function body")
     if args is not None:
         if not isinstance(args, obj.Cell):
             raise InvalidFormError("lambdas arguments should be a list")
         for arg in args:
             if not isinstance(arg, obj.Symbol):
                 raise InvalidFormError(
                     "lambda form arguments should be symbols")
     return obj.Lambda(self, args, body)
Ejemplo n.º 3
0
 def _eval_cond(self, node: obj.Cell):
     try:
         _, *exprs = node
     except ValueError:
         raise InvalidFormError(
             "cond form should consist of at least one condition"
             " and one expression to evaluate")
     try:
         for cond, expr in exprs:
             if self.eval(cond):
                 return _ReuseStack(expr)
     except (ValueError, TypeError):
         raise InvalidFormError(
             "each condition should be followed by an expression to be evaluated."
         )
Ejemplo n.º 4
0
 def _eval_quote(self, node: obj.Cell):
     try:
         _, expr = node
     except ValueError:
         raise InvalidFormError(
             "quote form should consist of a single argument"
             " which is a value to be quoted")
     return expr
Ejemplo n.º 5
0
 def _eval_begin(self, node: obj.Cell):
     try:
         _, *exprs = node
     except ValueError:
         raise InvalidFormError(
             "begin form should be followed by at least one expression")
     for expr in exprs[:-1]:
         self.eval(expr)
     return _ReuseStack(exprs[-1])
Ejemplo n.º 6
0
 def _eval_list(self, list: obj.Cell):
     if list is None:
         raise LogicError("Cannot evaluate an empty list")
     func, *args = list
     if isinstance(func, obj.Symbol) and func in self._special_forms:
         return self._special_forms[func](list)
     func = self.eval(func)
     args = [self.eval(arg) for arg in args]
     if not callable(func):
         raise InvalidFormError(
             "First value of an unquoted list should be a function")
     return func(*args)
Ejemplo n.º 7
0
 def _eval_car_to_cell(self, node: obj.Cell):
     try:
         car, expr = node
     except ValueError:
         raise InvalidFormError(
             "car should be followed by a single expression to evaluate")
     cell = self.eval(expr)
     if cell is None:
         raise LogicError("car cannot be used on an empty list")
     if not isinstance(cell, obj.Cell):
         raise EvalTypeError("car can only be called on a list")
     return cell
Ejemplo n.º 8
0
 def _eval_set(self, node: obj.Cell):
     err = InvalidFormError(
         "set! form should consist of memory reference (Symbol or cons cell)"
         " and an expression to evaluate")
     try:
         _, ref, expr = node
     except ValueError:
         raise err
     if isinstance(ref, obj.Symbol):
         ref_env = self._current_env.lookup(ref)
         if ref_env is None:
             raise EvaluationError(f"unknown symbol {ref}")
         ref_env[ref] = self.eval(expr)
     elif isinstance(ref, obj.Cell) and ref.car is sym.CAR:
         cell = self._eval_car_to_cell(ref)
         cell.value = self.eval(expr)
     else:
         raise err