def populateEnv(cls, env, ini_file):
        builtIns = [
            'symbol?', 'number?', 'b+', 'b-', 'b*', 'b/', 'b=', 'b<', 'car',
            'cdr', 'cons', 'set-car!', 'set-cdr!', 'null?', 'pair?', 'eq?',
            'procedure?', 'read', 'write', 'display', 'newline', 'eval',
            'apply', 'interaction-environment', 'load'
        ]
        for name in builtIns:
            id = Ident(name)
            env.define(id, BuiltIn(id))

        if os.path.exists(ini_file):
            #sys.stdout.write('path exists')
            path = env.lookup(Ident('load'))
            path.apply(Cons(StrLit(ini_file), Nil.getInstance()))
Beispiel #2
0
 def eval(self, exp, env):
     length = Special.util.length(exp)
     if(length != 3):
         self._error('invalid number of arguments for define')
         return Nil.getInstance()
     args = exp.getCdr().getCar()
     body = exp.getCdr().getCdr()
     if(args.isPair()):
         funcName = args.getCar()
         args = args.getCdr()
         if(not (funcName.isSymbol)):
             self._error('invalid function name')
             return Nil.getInstance()
         params = args
         while(params.isPair()):
             if(not (params.getCar().isSymbol())):
                 self._error('invalid parameter')
                 return Nil.getInstance()
             params = params.getCdr()
         function = Cons(Ident('lambda'), Cons(args, body))
         function = function.eval(env)
         env.define(funcName, function)
         return Nil.getInstance()
     if(args.isSymbol):
         env.define(args, body.getCar().eval(env))
         return Nil.getInstance()
     self._error('invalid expression with define')
Beispiel #3
0
 def populateEnv(env, file):
     # Array of builtIn names
     builtIns = [
         'read', 'newline', 'interaction-environment', 'load', 'car', 'cdr',
         'number?', 'symbol?', 'null?', 'pair?', 'procedure?', 'write',
         'display', 'eq?', 'cons', 'set-car!', 'set-cdr!', 'eval', 'apply',
         'b+', 'b-', 'b*', 'b/', 'b=', 'b<'
     ]
     # for each name in the builtIns array, define it in the environment
     for name in builtIns:
         node = Ident(name)
         env.define(node, BuiltIn(node))
     # as long as the file exists, load file into the environment using the load built-in function
     if os.path.exists(file):
         load = env.lookup(Ident('load'))
         load.apply(Cons(StrLit(file), Nil.getInstance()))
Beispiel #4
0
 def setEnv(cls, e):
     cls.env = e
     #TODO: Cleanup
     builtins = [
         "b+", "b-", "b/", "b*", "b=", "b<", "number?", "null?",
         "procedure?", "pair?", "cons", "car", "cdr", "set-car!",
         "set-cdr!", "eq?", "interaction-environment", "load", "read",
         "write", "display", "eval", "apply", "newline"
     ]
     for i in builtins:
         cls.env.define(Ident(i), Cons(BuiltIn(StrLit(i)),
                                       Nil.getInstance()))
Beispiel #5
0
 def __apply0(self):
     #sys.stdout.write('inside apply0')
     sym = self.symbol.getName()
     if sym == "read":
         scan = Scanner(sys.stdin)
         parse = Parser(scan, TreeBuilder())
         rest = parse.parseExp()
         if rest != None:
             return rest
         return Ident("end-of-file")
     elif sym == "newline":
         sys.stdout.write('\n')
         sys.stdout.flush()
         return Nil.getInstance()
     elif sym == "interaction-environment":
         return BuiltIn.env
     else:
         self._error("argument error 0")
         return Nil.getInstance()
Beispiel #6
0
    def eval(self, exp, env):
        #sys.stdout.write('inside define.eval')
        t = Special.util.length(exp)
        if t < 3:
            self._error("define error")
            return Nil.getInstance()
        elif exp.getCdr().getCar().isPair():
            vars = exp.getCdr().getCar()
            parms = vars.getCdr()
            sym = vars.getCar()

            rest = exp.getCdr().getCdr()
            func = Cons(Ident("lambda"), Cons(parms, rest))
            env.define(sym, func.eval(env))
            return Nil.getInstance()
        else:
            vars = exp.getCdr().getCar()
            val = exp.getCdr().getCdr().getCar()
            if vars.isSymbol():
                if t == 3:
                    env.define(vars, val.eval(env))
            return Nil.getInstance()
Beispiel #7
0
 def buildIdent(self,n):
     return Ident(n)
Beispiel #8
0
            elif s == "set!":
                self.form = Set()
            elif s == "quote":
                self.form = Quote()
            else:
                self.form = Regular()

    def print(self, n, p=False):
        self.form.print(self, n, p)

    def getCar(self):
        return self.car

    def getCdr(self):
        return self.cdr

    def setCar(self, a):
        self.car = a
        self.parseList()

    def setCdr(self, d):
        self.cdr = d

    def isPair(self):
        return True


if __name__ == "__main__":
    c = Cons(Ident("Hello"), Ident("World"))
    c.print(0)
Beispiel #9
0
        if val == None and self.env == None:
            self._error("undefined variable " + id.getName())
            return Nil.getInstance()
        elif val == None:
            # look up the identifier in the enclosing scope
            return self.env.lookup(id)
        else:
            # get the value out of the list we got from find()
            return val.getCar()

    def define(self, id, value):
        self.frame = Cons(Cons(id, Cons(value, Nil.getInstance())), self.frame)

    def assign(self, id, value):
        val = Environment.__find(id, self.frame)
        if val == None and self.env == None:
            self._error("undefined variable " + id.getName())
            return Nil.getInstance()
        elif val == None:
            # look up the identifier in the enclosing scope
            return self.env.assign(id, value)
        else:
            # set the value of the list we got to 'value'
            return val.setCar(value)


if __name__ == "__main__":
    env = Environment()
    env.define(Ident("foo"), IntLit(42))
    env.print(0)
Beispiel #10
0
    def apply(self, args):
        argLength = self.util.length(args)
        name = self.symbol.strVal
        if name == "b+":  #Binary Addition
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            sum = args.getCar().intVal + args.getCdr().getCar().intVal
            return IntLit(sum)
        elif name == "b-":  #Binary Subtraction
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            diff = args.getCar().intVal - args.getCdr().getCar().intVal
            return IntLit(diff)
        elif name == "b*":  #Binary Multiplication
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            return IntLit(args.getCar().intVal * args.getCdr().getCar().intVal)
        elif name == "b/":  #Binary Division
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            return IntLit(args[0].intVal / args.getCdr().getCar().intVal)
        elif name == "number?":  #Check if is a number
            if argLength is not 1:
                return self.invalidArgCount()
            if args.getCar().isNumber():
                return BoolLit.getInstance(True)
            return BoolLit.getInstance(False)
        elif name == "b=":
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            return BoolLit.getInstance(True) if args.getCar(
            ).intVal == args.getCdr().getCar().intVal else BoolLit.getInstance(
                False)
        elif name == "b<":
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isNumber() or not args.getCdr().getCar(
            ).isNumber():
                return self.invalidArgType()
            return BoolLit.getInstance(True) if args.getCar(
            ).intVal < args.getCdr().getCar().intVal else BoolLit.getInstance(
                False)
        elif name == "null?":
            if argLength is not 1:
                return self.invalidArgCount()
            if args.getCar().isNull():
                return BoolLit.getInstance(True)
            return BoolLit.getInstance(False)
        elif name == "procedure?":
            if argLength is not 1:
                return self.invalidArgCount()
            if args.getCar().isProcedure():
                return BoolLit.getInstance(True)
            return BoolLit.getInstance(False)
        elif name == "pair?":
            if argLength is not 1:
                return self.invalidArgCount()
            return BoolLit.getInstance(
                True) if args.getCar().isPair() else BoolLit.getInstance(False)
        elif name == "cons":
            if argLength is not 2:
                return self.invalidArgCount()
            return Cons(args.getCar(), args.getCdr().getCar())
        elif name == "car":
            if argLength is not 1:
                return self.invalidArgCount()
            if not args.getCar().isPair():
                return self.invalidArgType()
            return args.getCar().getCar()
        elif name == "cdr":
            if argLength is not 1:
                return self.invalidArgCount()
            if not args.getCar().isPair():
                return self.invalidArgType()
            return args.getCar().getCdr()
        elif name == "set-car!":
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isPair():
                return self.invalidArgType()
            args.getCar().setCar(args.getCdr().getCar())
            return Nil.getInstance()
        elif name == "set-cdr!":
            if argLength is not 2:
                return self.invalidArgCount()
            if not args.getCar().isPair():
                return self.invalidArgType()
            args.getCar().setCdr(args.getCdr().getCar())
            return Nil.getInstance()
        elif name == "eq?":
            if args.getCar().isSymbol() and args.getCdr().getCar().isSymbol():
                arg1_name = args.getCar().getName()
                arg2_name = args.getCdr().getCar().getName()
                return BoolLit.getInstance(arg1_name == arg2_name)
            return BoolLit.getInstance(args.getCar() == args.getCdr().getCar())

        #load
        elif name == "load":
            if not args.getCar().isString():
                return self.invalidArgType()
            filename = args.getCar().strVal
            try:
                scanner = Scanner(open(filename))
                builder = TreeBuilder()
                parser = Parser(scanner, builder)

                root = parser.parseExp()
                while root != None:
                    root.eval(BuiltIn.env)
                    root = parser.parseExp()
            except IOError:
                self._error("could not find file " + filename)
            return Nil.getInstance()  # or Unspecific.getInstance()

        #read, calls parser and returns a parse tree
        elif name == "read":
            scanner = Scanner(sys.stdin)
            builder = TreeBuilder()
            parser = Parser(scanner, builder)
            #return parse tree here
            if parser != None:
                return parser.parseExp()
            return Ident('End of Parse Tree')

        #write, calls pretty printer
        elif name == "write":
            if argLength is not 1:
                return self.invalidArgCount()
            args.getCar().print(-1)
            return Nil.getInstance()

        #display, calls pretty printer
        elif name == "display":
            if argLength is not 1:
                return self.invalidArgCount()
            StrLit.include_quote = 0
            args.getCar().print(-1)
            StrLit.include_quote = 1
            return Nil.getInstance()

        #eval, calls python eval function
        elif name == 'eval':
            if argLength is not 2:
                return self.invalidArgCount()
            if args.getCdr().getCar().isEnvironment():
                return args.getCar().eval(args.getCdr().getCar())
            return self.invalidArgType()

        #apply, calls python apply function
        elif name == "apply":
            if argLength is not 2:
                return self.invalidArgCount()
            return args.getCar().apply(args.getCdr().getCar())

        #interaction-environment, returns a pointer to interpreter's global environment
        elif name == "interaction-environment":
            return BuiltIn.env

        #newline without optional port argument
        elif name == "newline":
            sys.stdout.write('\n')
            sys.stdout.flush()
            return Nil.getInstance()

        return StrLit("Error: BuiltIn.apply not yet implemented for " +
                      self.symbol)
    def apply(self, args):
        # Retrive the length of the argument
        length = BuiltIn.util.length(args)

        # Error check for invalid number of arguments
        if (length > 2):
            self._error('invalid expression: too many arguments')
            return Nil.getInstance()

        # Extract the name
        name = self.symbol.getName()

        # Apply for arguments of length 0
        if (length == 0):
            if (name == "read"):
                scanner = Scanner(sys.stdin)
                builder = TreeBuilder()
                parser = Parser(scanner, builder)

                result = parser.parseExp()
                if (result != None):
                    return result
                return Ident('end-of-file')
            if (name == "newline"):
                sys.stdout.write('\n')
                sys.stdout.flush()
                return Nil.getInstance()
            if (name == "interaction-environment"):
                return self.env
            self._error('unknown built-in function')
            return Nil.getInstance()

        # Apply for arguments of length 1
        if (length == 1):
            # Retrieve the argument
            arg1 = args.getCar()

            # Apply for load
            if (name == "load"):
                if (not arg1.isString()):
                    self._error("wrong type of argument")
                    return Nil.getInstance()
                filename = arg1.getStrVal()
                try:
                    scanner = Scanner(open(filename))
                    builder = TreeBuilder()
                    parser = Parser(scanner, builder)

                    root = parser.parseExp()
                    while root != None:
                        root.eval(BuiltIn.env)
                        root = parser.parseExp()
                except IOError:
                    self._error("could not find file " + filename)
                return Nil.getInstance()  # or Unspecific, if implemented

            # Apply for car
            if (name == "car"):
                return arg1.getCar()

            # Apply for cdr
            if (name == "cdr"):
                return arg1.getCdr()

            # Apply for number?
            if (name == "number?"):
                return BoolLit.getInstance(arg1.isNumber())

            # Apply for symbol?
            if (name == "symbol?"):
                return BoolLit.getInstance(arg1.isSymbol())

            # Apply for null?
            if (name == "null?"):
                return BoolLit.getInstance(arg1.isNull())

            # Apply for pair?
            if (name == "pair?"):
                return BoolLit.getInstance(arg1.isPair())

            # Apply for procedure?
            if (name == "procedure?"):
                return BoolLit.getInstance(arg1.isProcedure())

            # Apply for write
            if (name == "write"):
                arg1.print(-1)
                return Nil.getInstance()

            # Apply for display
            if (name == "display"):
                StrLit.printQuotes = False
                arg1.print(-1)
                StrLit.printQuotes = True
                return Nil.getInstance()

            self._error('unknown built-in function')
            return Nil.getInstance()

        # Apply for arguments of length 2
        if (length == 2):
            # Retrieve the two arguments
            arg1 = args.getCar()
            arg2 = args.getCdr().getCar()

            if (name == "eq?"):
                if (arg1.isSymbol()):
                    if (arg2.isSymbol()):
                        name1 = arg1.getName()
                        name2 = arg2.getName()
                        return BoolLit.getInstance(name1 == name2)
                    else:
                        return BoolLit.getInstance(False)
                return BoolLit.getInstance(arg1 == arg2)
            if (name == "cons"):
                return Cons(arg1, arg2)
            if (name == "set-car!"):
                arg1.setCar(arg2)
                return Nil.getInstance()
            if (name == "set-cdr!"):
                arg1.setCdr(arg2)
                return Nil.getInstance()
            if (name == "eval"):
                return arg1.eval(arg2)
            if (name == "apply"):
                return arg1.apply(arg2)
            if (name[0] == 'b'):
                if (arg1.isNumber()):
                    if (arg2.isNumber()):
                        arg1 = arg1.getIntVal()
                        arg2 = arg2.getIntVal()
                        if (name == 'b+'):
                            return IntLit(arg1 + arg2)
                        if (name == 'b-'):
                            return IntLit(arg1 - arg2)
                        if (name == 'b*'):
                            return IntLit(arg1 * arg2)
                        if (name == 'b/'):
                            return IntLit(arg1 / arg2)
                        if (name == 'b='):
                            return BoolLit.getInstance(arg1 == arg2)
                        if (name == 'b<'):
                            return BoolLit.getInstance(arg1 < arg2)
                        self._error('unknown built-in function')
                        return Nil.getInstance()
                    else:
                        self._error('invalid argument type')
                        return Nil.getInstance()
                else:
                    self._error('invalid argument type')
                    return Nil.getInstance()
            self._error('unknown built-in function')
            return Nil.getInstance()
Beispiel #12
0
                sys.stdout.write(", name = " + tok.getName() + "\n")
            else:
                sys.stdout.write("\n")
            sys.stdout.flush()

            tok = scanner.getNextToken()
    else:
        # Create parser
        builder = TreeBuilder()
        parser = Parser(scanner, builder)

        env = Environment()
        BuiltIn.setEnv(env)

        #Environment.populateEnv(env, ini_file)
        id = Ident("b+")
        env.define(id, BuiltIn(id))

        id = Ident("b-")
        env.define(id, BuiltIn(id))

        id = Ident("b*")
        env.define(id, BuiltIn(id))

        id = Ident("b/")
        env.define(id, BuiltIn(id))

        id = Ident("b=")
        env.define(id, BuiltIn(id))

        id = Ident("b<")