예제 #1
0
def evaluate(atom, called_from="", return_object=False):
	if atom.quote:
		atom.quote -= 1
		return atom

	elif atom.type == Atom.KEYWORD:
		return atom.data

	elif atom.type == Atom.SYMBOL:
		value = Environment.get_symbol_value(atom.data)
		if value is not None:
			return value
		else:
			raise LispError("%s: Undefined symbol %s" % (called_from, atom.data))

	elif atom.type == Atom.CONS:
		if atom.data.quote:
			atom.data.quote -= 1
			return atom

		fun = atom.data.first.data
		if fun not in Functions.functions:
			raise LispError("%s: Undefined function %s" % (called_from, fun))

		args = cons_to_list(atom.data.second.data)
		result = Functions.functions[fun](fun, args)
		return result

	else:
		return atom if return_object else atom.data
예제 #2
0
def symbol_read_line(fun, args):
    handle = eval(args[0], fun)
    if handle not in file_handles:
        raise LispError("READ-LINE: File handle not active")
    try:
        while True:
            line = file_handles[handle].readline()
            if not line:
                raise LispError("READ-LINE: End of file")
            if line != "\n":
                break

        if line[-1] == "\n":
            line = line[:-1]
        return Atom.Atom(Atom.Atom.STRING, line)
    except Exception as e:
        raise LispError(e.__str__())
예제 #3
0
def symbol_read_char(fun, args):
    handle = eval(args[0], fun)
    if handle not in file_handles:
        raise LispError("READ-CHAR: File handle not active")
    ch = file_handles[handle].read(1)
    if not ch:
        return Atom.make_symbol("EOF")
    return "\"%s\"" % ch
예제 #4
0
def symbol_slash(fun, args):
    result = float(eval(args[0], fun))
    for x in args[1:]:
        x = eval(x, fun)
        if x == 0:
            raise LispError("/: Division by zero")
        result /= x
    return result
예제 #5
0
def symbol_read(fun, args):
    handle = eval(args[0], fun)
    if handle not in file_handles:
        raise LispError("READ: File handle not active")
    try:
        parser = LispParser.LispParser(file_handles[handle])
        return parser.read_object()
    except StopIteration:
        return Atom.make_symbol("EOF")
예제 #6
0
def symbol_open(fun, args):
    global file_handles, next_handle
    filename = eval(args[0], fun)
    try:
        file_handles[next_handle] = open(filename)
        next_handle += 1
        return next_handle - 1
    except Exception as e:
        raise LispError("OPEN: Couldn't open '%s' (%s)" %
                        (filename, e.__str__()))
예제 #7
0
    def _process_character(self, ch):
        if self._in_comment:
            if ch == "\n":
                # end comment
                self._in_comment = False

        elif self._in_quotation or self._in_character_quote:
            if self._in_escape:
                self._in_escape = False
                if ch == "\\":
                    self._token += "\\"
                elif ch == "\r":
                    self._token += "\r"
                elif ch == "\n":
                    self._token += "\n"
                elif ch == "\t":
                    self._token += "\t"
                elif ch == "\"":
                    self._token += "\""
                else:
                    raise LispError("Unknown escape sequence \\%s" % ch)

            elif ch == "\\":
                self._in_escape = True
                return

            else:
                self._token += ch
                if ch == "\"" and not self._in_character_quote:
                    self._in_quotation = False
                    self._finish_token = self._token
                    self._token = ""
                self._in_character_quote = False

        elif ch == ";":
            # begin comment
            self._in_comment = True

        elif ch == "'":
            # quoted object begins here
            self._quote_level = self._level
            #self._quote_atom = self._this_atom

        elif ch.isspace() or ch == ",":
            # token delimiter
            if self._last and not self._last.isspace():
                self._finish_token = self._token
                self._token = ""

        elif ch == "(":
            if self._last == "#":
                self._token = "#("
                while True:
                    peek = self._input.read(1)
                    self._token += peek
                    if peek == ")":
                        break
                self._finish_token = self._token
                self._token = ""
            else:
                # open s-expression
                self._level += 1
                self._open_paren = True

        elif ch == "[":
            # open m-expression
            self._place_first_atom = Atom.detect_type(self._token)
            self._token = ""
            self._level += 1
            self._open_paren = True

        elif ch == ")" or ch == "]":
            if self._level:
                # close s- or m-expression
                self._close_paren = True
                self._finish_token = self._token
                self._token = ""
            else:
                self._finish_token = self._token
                self._token = ""
                self._input.putback(")")

        elif ch == "\"":
            # open/close string
            self._token += ch
            self._in_quotation = True

        else:
            # add to token
            self._token += ch
            if self._token == "#\\":
                self._in_character_quote = True

        self._last = ch
예제 #8
0
def symbol_close(fun, args):
    handle = eval(args[0], fun)
    if handle not in file_handles:
        raise LispError("CLOSE: File handle not active")
    file_handles[handle].close()
    file_handles.pop(handle)