<commit_before># The Lithp interpreter is requires Python 3000 to function.  
# For more information:
#   http://www.slideshare.net/jza/python-3000
#   http://www.ibm.com/developerworks/linux/library/l-python3-1/
#   http://www.python.org/dev/peps/pep-3000/
#   http://www.python.org/dev/peps/
#   http://www.python.org/dev/peps/pep-0008/

import getopt, sys
from lisp import Lisp
from env import Environment
from scanner import Scanner
from function import Function

NAME = "Lithp"
VERSION = "v0.0.1"
PROMPT = "lithp"
DEPTH_MARK = "."

INVALID_OPS = 1

class Lithp(Lisp):
    """ The Lithper class is the interpreter driver.  It does the following:
            1. Initialize the global environment
            2. Parse the cl arguments and act on them as appropriate
            3. Initialize the base Lisp functions
            4. Read input
            5. Evaluate
            6. Print
            7. Loop back to #4
    """
    def __init__( self):
        iostreams=(sys.stdin, sys.stdout, sys.stderr)
        (self.stdin, self.stdout, self.stderr) = iostreams
        
        self.debug = False
        self.verbose = True
        self.print_banner()

        self.scanner = Scanner()
        self.environment = Environment()
        
        self.init()

    def init(self):
        # Define core functions
        self.environment.set( "print", Function( self.println))
        self.environment.set("foo", Function(self.dummy))

    def usage(self):
        self.print_banner()
        print
        print(NAME.lower(), " <options> [lithp files]\n")

    def print_banner(self):
        print("The ", NAME, " programming shell ", VERSION)
        print("   by Fogus, http://fogus.me")
        
    def repl(self):
        print(self.environment)

        while True:
            source = self.get_complete_command() # Stealing a line from CLIPS

            if source in ["(quit)"]: # `quit` is not in the original Lisp either, but alas
                break
 
            print(source)

    def get_complete_command(self, line="", depth=0):
        if line != "":
            line = line + " "

        if self.environment.level != 0:
            prompt = PROMPT + " %i%s " % (self.environment.level, DEPTH_MARK * (depth+1))
        else:
            if depth == 0:
                prompt = PROMPT + "> "
            else:
                prompt = PROMPT + "%s " % (DEPTH_MARK * (depth+1))

            line = line  + self.read_line(prompt)
            balance = 0                    # Used to balance the parens
            for ch in line:
                if ch == "(":
                    balance = balance + 1  # This is not perfect, but will do for now
                elif ch == ")":
                    balance = balance - 1  # Too many right parens is a problem
            if balance != 0:               # Balanced parens gives zero
                return self.get_complete_command( line, depth+1)
            else:
                return line

    def read_line( self, prompt) :
        if prompt :
            self.stdout.write("%s" % prompt)
            self.stdout.flush()
        line = self.stdin.readline()    
        if line[-1] == "\n":
            line = line[:-1]

        return line  
        

if __name__ == '__main__':
    lithp = Lithp()
    <commit_msg>Trying to catch too many right parens<commit_after># The Lithp interpreter is requires Python 3000 to function.  
# For more information:
#   http://www.slideshare.net/jza/python-3000
#   http://www.ibm.com/developerworks/linux/library/l-python3-1/
#   http://www.python.org/dev/peps/pep-3000/
#   http://www.python.org/dev/peps/
#   http://www.python.org/dev/peps/pep-0008/

import getopt, sys
from lisp import Lisp
from env import Environment
from scanner import Scanner
from function import Function

NAME = "Lithp"
VERSION = "v0.0.1"
PROMPT = "lithp"
DEPTH_MARK = "."

INVALID_OPS = 1

class Lithp(Lisp):
    """ The Lithper class is the interpreter driver.  It does the following:
            1. Initialize the global environment
            2. Parse the cl arguments and act on them as appropriate
            3. Initialize the base Lisp functions
            4. Read input
            5. Evaluate
            6. Print
            7. Loop back to #4
    """
    def __init__( self):
        iostreams=(sys.stdin, sys.stdout, sys.stderr)
        (self.stdin, self.stdout, self.stderr) = iostreams
        
        self.debug = False
        self.verbose = True
        self.print_banner()

        self.scanner = Scanner()
        self.environment = Environment()
        
        self.init()

    def init(self):
        # Define core functions
        self.environment.set( "print", Function( self.println))
        self.environment.set("foo", Function(self.dummy))

    def usage(self):
        self.print_banner()
        print
        print(NAME.lower(), " <options> [lithp files]\n")

    def print_banner(self):
        print("The ", NAME, " programming shell ", VERSION)
        print("   by Fogus, http://fogus.me")
        
    def repl(self):
        print(self.environment)

        while True:
            source = self.get_complete_command() # Stealing a line from CLIPS

            if source in ["(quit)"]: # `quit` is not in the original Lisp either, but alas
                break
 
            print(source)

    def get_complete_command(self, line="", depth=0):
        if line != "":
            line = line + " "

        if self.environment.level != 0:
            prompt = PROMPT + " %i%s " % (self.environment.level, DEPTH_MARK * (depth+1))
        else:
            if depth == 0:
                prompt = PROMPT + "> "
            else:
                prompt = PROMPT + "%s " % (DEPTH_MARK * (depth+1))

            line = line  + self.read_line(prompt)
            balance = 0                    # Used to balance the parens
            for ch in line:
                if ch == "(":
                    balance = balance + 1  # This is not perfect, but will do for now
                elif ch == ")":
                    balance = balance - 1  # Too many right parens is a problem
            if balance > 0:               # Balanced parens gives zero
                return self.get_complete_command( line, depth+1)
            elif balance < 0:
                raise ValueError("Invalid paren pattern")
            else:
                return line

    def read_line( self, prompt) :
        if prompt :
            self.stdout.write("%s" % prompt)
            self.stdout.flush()
        line = self.stdin.readline()    
        if line[-1] == "\n":
            line = line[:-1]

        return line  
        

if __name__ == '__main__':
    lithp = Lithp()
    
{'fraction_non_alphanumeric': 0.10955014198176655, 'fraction_numerical': 0.01270363174413391, 'mean_word_length': 1.6972994760177347, 'pattern_counts': {'":': 8, '<': 6, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 10, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6132430', 'n_tokens_mistral': 2048, 'n_tokens_neox': 1920, 'n_words': 567}