Ejemplo n.º 1
0
    def __apply1(self, arg):
        #sys.stdin.write('inside apply1')
        sym = self.symbol.getName()
        if sym == "car":
            return arg.getCar()
        elif sym == "cdr":
            return arg.getCdr()
        elif sym == "number?":
            return BoolLit.getInstance(arg.isNumber())
        elif sym == "symbol?":
            return BoolLit.getInstance(arg.isSymbol())
        elif sym == "null?":
            return BoolLit.getInstance(arg.isNull())
        elif sym == "pair?":
            return BoolLit.getInstance(arg.isPair())
        elif sym == "procedure?":
            return BoolLit.getInstance(arg.isProcedure())
        elif sym == "write":
            arg.print(-1)
            return Nil.getInstance()
        elif sym == "display":
            StrLit.DoubleQuotes = False
            arg.print(-1)
            StrLit.DoubleQuotes = True
            return Nil.getInstance()
        elif sym == "load":
            #sys.stdout.write('load successful')
            if not arg.isString():
                self._error("first argument error")
                return Nil.getInstance()
            f = arg.getStrVal()
            #sys.stdout.write('before try')
            try:
                scan = Scanner(open(f))
                #sys.stdout.write('1')
                build = TreeBuilder()
                #sys.stdout.write('2')
                parse = Parser(scan, build)
                #sys.stdout.write('3')
                head = parse.parseExp()
                #sys.stdout.write('4')
                while head != None:
                    head.eval(BuiltIn.env)
                    #sys.stdout.write('loop1')
                    head = parse.parseExp()
                    #sys.stdout.write('loop2')

            except IOError:
                self._error("file not found " + f)

            return Nil.getInstance()
        else:
            self._error("first argument error")
            return Nil.getInstance()
Ejemplo n.º 2
0
 def __evaluate(self, exp, env):
     if exp.isNull():
         return Nil.getInstance()
     cnd = exp.getCar()
     if Special.util.length(cnd) < 1:
         self._error("first cond error")
         return Nil.getInstance()
     name = cnd.getCar()
     rest = cnd.getCdr()
     if name.isSymbol():
         if test.getName() == "else":
             if not (rest.isNull() or exp.getCdr().isNull()):
                 self._error("second cond error")
                 return Nil.getInstance()
             return Special.util.begin(rest, env)
         val = test.eval(env)
         if val != BoolLit.getInstance(False):
             if rest.isNull():
                 return val
     t = rest.getCar()
     if t.isSymbol():
         if t.getName() == "=>":
             if Special.util.length(rest) != 2:
                 self._error("third cond error")
                 return Nil.getInstance()
             func = body.getCdr().getCar().eval(env)
             return func.apply(val)
         return Special.util.begin(body, env)
     else:
         return self.__evalClauses(exp.getCdr(), env)
Ejemplo n.º 3
0
 def __apply2(self, arg1, arg2):
     #sys.stdout.write('inside apply2')
     sym = self.symbol.getName()
     if sym == "eq?":
         return BoolLit.getInstance(arg1 is arg2)
     elif sym == "cons":
         return Cons(arg1, arg2)
     elif sym == "set-car!":
         arg1.setCar(arg2)
         return Nil.getInstance()
     elif sym == "set-cdr!":
         arg1.setCdr(arg2)
         return Nil.getInstance()
     elif sym == "eval":
         if arg2.isEnvironment():
             return arg1.eval(arg2)
         self._error("second argument error")
         return Nil.getInstance()
     elif sym == "apply":
         return arg1.apply(arg2)
     else:
         if sym[0] == "b":
             pass
         if len(sym) == 2:
             if arg1.isNumber():
                 if arg2.isNumber():
                     return self.__IntOps(arg1.getIntVal(),
                                          arg2.getIntVal())
                 self._error("argument error")
                 return Nil.getInstance()
             self._error("argument error")
         return Nil.getInstance()
Ejemplo n.º 4
0
 def __IntOps(self, arg1, arg2):
     sym = self.symbol.getName()
     if sym == "b+":
         return IntLit(arg1 + arg2)
     elif sym == "b-":
         return IntLit(arg1 - arg2)
     elif sym == "b*":
         return IntLit(arg1 * arg2)
     elif sym == "b/":
         return IntLit(arg1 / arg2)
     elif sym == "b=":
         return BoolLit.getInstance(arg1 == arg2)
     elif sym == "b<":
         return BoolLit.getInstance(arg1 < arg2)
     else:
         self._error("Unknown BuiltIn function")
         return Nil.getInstance()
Ejemplo n.º 5
0
 def eval(self, exp, env):
     condition = exp.getCdr().getCar()
     if condition.eval(env) == BoolLit.getInstance(True):
         return exp.getCdr().getCdr().getCar().eval(env)
     elif not (exp.getCdr().getCdr().getCdr() == Nil.getInstance()):
         return exp.getCdr().getCdr().getCdr().getCar().eval(env)
     else:
         return StrLit("else expression not found")
Ejemplo n.º 6
0
 def eval(self, exp, env):
     #sys.stdout.write('inside apply.eval')
     t = Special.util.length(exp)
     if t < 3 or t > 4:
         self._error("special if error")
         return Nil.getInstance()
     temp = exp.getCdr().getCar()
     temp1 = exp.getCdr().getCdr().getCar()
     if t == 3:
         eexp = Nil.getInstance()
     else:
         eexp = exp.getCdr().getCdr().getCdr().getCar()
     if temp.eval(env) != BoolLit.getInstance(False):
         return temp1.eval(env)
     else:
         return eexp.eval(env)
Ejemplo n.º 7
0
 def eval(self, exp, env):
     n = Special.util.length(exp)
     # Test for a valid if statement
     if (n < 3 or n > 4):
         self._error(
             'invalid expression, incorrect number of arguments for if statement'
         )
         return Nil.getInstance()
     # extract the conditional test from the if statement
     testExp = exp.getCdr().getCar()
     # extract the expression to evaluate if the conditional evaluates to true
     trueExp = exp.getCdr().getCdr().getCar()
     # extract the expression to evaluate if the conditional evaluates to false
     if (n == 3):
         elseExp = Nil.getInstance(
         )  # Else expression is unspecified, return Unspecified if implemented
     else:
         elseExp = exp.getCdr().getCdr().getCdr().getCar()
     # evaluate the test and return the desired expression
     if (testExp.eval(env) == BoolLit.getInstance(True)):
         return trueExp.eval(env)
     else:
         return elseExp.eval(env)
Ejemplo n.º 8
0
 def buildBoolLit(self,b):
     return BoolLit.getInstance(b)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
0
 def eval(self, exp, env):
     cond = exp.getCdr()
     while(cond.getCdr() != Nil.getInstance() and cond.getCar().getCar().eval(env) == BoolLit.getInstance(False)):
         cond = cond.getCdr()
     if cond == Nil.getInstance():
         return Nil.getInstance()
     else:
         return cond.getCar().getCdr().getCar().eval(env)
Ejemplo n.º 12
0
    def apply(self, args):

        ## The easiest way to implement BuiltIn.apply is as an
        ## if-then-else chain testing for the different names of
        ## the built-in functions.  E.g., here's how load could
        ## be implemented:

        # 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.getInstance()

        # this may or may not work

        # get args (arg 1 is the car, arg 2 is the car of the cdr)
        if args == None:
            return Nil.getInstance()
        name = self.symbol.getName()
        car = args.getCar()
        if car.isNull():
            car = Nil.getInstance()
        cdr = args.getCdr()
        # if there is no arg 2, just set it to nil
        if cdr.isNull():
            cdr = Nil.getInstance()
        # otherwise arg2 is the car of the cdr
        else:
            cdr = cdr.getCar()

        if name == "b+":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return IntLit(x + y)
            else:
                return StrLit("Invalid arguments for b+")
        elif name == "b-":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return IntLit(x - y)
            else:
                return StrLit("Invalid arguments for b-")
        elif name == "b*":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return IntLit(x * y)
            else:
                return StrLit("Invalid arguments for b*")
        elif name == "b/":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return IntLit(x / y)
            else:
                return StrLit("Invalid arguments for b/")
        elif name == "b=":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return BoolLit.getInstance(x == y)
            else:
                return StrLit("Invalid arguments for b=")
        elif name == "b<":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return BoolLit.getInstance(x < y)
            else:
                return StrLit("Invalid arguments for b<")
        elif name == "b>":
            if car.isNumber() and cdr.isNumber():
                x = car.intVal
                y = cdr.intVal
                return BoolLit.getInstance(x > y)
            else:
                return StrLit("Invalid arguments for b>")
        elif name == "car":
            if car.isPair():
                return car.getCar()
            return StrLit("Wrong number of arguements")
        elif name == "cdr":
            if car.isPair():
                return car.getCdr()
            return StrLit("Wrong number of arguements")
        elif name == "cons":
            if cdr.isPair():
                return Cons(car, cdr)
            return StrLit("Wrong number of arguements")
        elif name == "set-car!":  #does this work??
            car.setCar(cdr)
            return car
        elif name == "set-cdr!":  #does this work??
            car.setCdr(cdr)
            return car
        elif name == "symbol?":
            return BoolLit.getInstance(car.isSymbol())
        elif name == "number?":
            return BoolLit.getInstance(car.isNumber())
        elif name == "null?":
            return BoolLit.getInstance(car == Nil.getInstance())
        elif name == "pair?":
            return BoolLit.getInstance(car.isPair())
        elif name == "eq?":  #come back to this
            if car.isBool() and cdr.isBool():
                return BoolLit.getInstance(car.boolVal == cdr.boolVal)
            elif car.isNumber() and cdr.isNumber():
                return BoolLit.getInstance(car.intVal == cdr.intVal)
            elif car.isSymbol() and cdr.isSymbol():
                return BoolLit(car.getName().equals(cdr.getName()))
            elif car == Nil.getInstance():
                return BoolLit.getInstance(True)
            elif (car.isPair() and cdr.isPair()):
                opener = Cons(car.getCar(),
                              Cons(cdr.getCar(), Nil.getInstance()))
                closer = Cons(car.getCdr(),
                              Cons(cdr.getCdr(), Nil.getInstance()))
                return BoolLit(apply(opener).boolVal and apply(closer).boolVal)

        elif name == "procedure?":
            return BoolLit.getInstance(car.isProcedure())
        elif name == "display":
            return car
        elif name == "newline":  #come back to this
            StrLit("")
        elif name == "read":
            parser = Parser(Scanner(sys.stdin))  #com back to this
            return parser.parseExp()
        elif name == "write":  #come back to this
            car.print(0)
            return StrLit("")
        elif name == "eval":  #come back
            return car
        elif name == "apply":  #come back
            return car.apply(cdr)
        elif name == "interaction-development":  #come back
            interaction_environment.print(0)
        elif name == "load":  #come back
            if not car.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.getInstance()
        else:
            car.print(0)
            return Nil.getInstance()
        return StrLit(">")