Exemplo n.º 1
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")
Exemplo n.º 2
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()))
Exemplo n.º 3
0
 def eval(self, exp, env):
     key = exp.getCdr().getCar()
     val = exp.getCdr().getCdr().getCar()
     # if defining a variable
     if key.isSymbol():
         env.define(key, val)
     # if defining a function
     else:
         func = Closure(
             Cons(exp.getCdr().getCar().getCdr(),
                  exp.getCdr().getCdr()), env)
         env.define(key.getCar(), func)
     return StrLit("no values returned")
Exemplo n.º 4
0
    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()))
Exemplo n.º 5
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()))
Exemplo n.º 6
0
 def buildStrLit(self,s):
     return StrLit(s)
Exemplo n.º 7
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)
Exemplo n.º 8
0
    def apply(self, args):
        if args == None:
            return None

        symbolName = self.symbol.getName()

        arg1 = args.getCar()

        if arg1 == None or arg1.isNull():
            arg1 = Nil()

        arg2 = args.getCdr()

        if arg2 == None or arg2.isNull():
            arg2 = Nil()

        if symbolName == '+':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return IntLit(x + y)
            else:
                print('bad argument for +')
                return StrLit("")
        elif symbolName == '-':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return IntLit(x - y)
            else:
                print('bad argument for -')
                return StrLit("")
        elif symbolName == '*':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return IntLit(x * y)
            else:
                print('bad argument for *')
                return StrLit("")
        elif symbolName == '/':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return IntLit(x / y)
            else:
                print('bad argument for /')
                return StrLit("")
        elif symbolName == '=':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return BoolLit(x == y)
            else:
                print('bad argument for =')
        elif symbolName == '<':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return BoolLit(x < y)
            else:
                print('bad argument for <')
        elif symbolName == '>':
            if arg1.isNumber() and arg2.isNumber():
                x = arg1.getIntVal()
                y = arg2.getIntVal()
                return BoolLit(x > y)
            else:
                print('bad argument for >')
        elif symbolName == 'car':
            if arg1.isNull():
                return arg1
            return arg1.getCar()
        elif symbolName == 'cdr':
            if arg1.isNull():
                return arg1
            return arg1.getCdr()
        elif symbolName == 'cons':
            return Cons(arg1, arg2)
        elif symbolName == 'set-car!':
            arg1.setCar(arg2)
            return arg1
        elif symbolName == 'set-cdr!':
            arg1.setCdr(arg2)
            return arg1
        elif symbolName == 'symbol?':
            return BoolLit(arg1.isSymbol())
        elif symbolName == 'number?':
            return BoolLit(arg1.isNumber())
        elif symbolName == 'null?':
            return BoolLit(arg1.isNull())
        elif symbolName == 'pair?':
            return BoolLit(arg1.isPair())
        elif symbolName == 'eq?':
            if (arg1.isBool() and arg2.isBool()) or (arg1.isNumber()
                                                     and arg2.isNumber()) or (
                                                         arg1.isString()
                                                         and arg2.isString()):
                return BoolLit(arg1 == arg2)
            elif arg1.isSymbol() and arg2.isSymbol():
                return BoolLit(arg1.getName() == arg2.getName())
            elif arg1.isNull() and arg2.isNull():
                return BoolLit(True)
            elif arg1.isPair() and arg2.isPair():
                frontArgs = Cons(arg1.getCar(), Cons(arg2.getCar(), Nil))
                backArgs = Cons(arg1.getCdr(), Cons(arg2.getCdr(), Nil))
                return BoolLit(apply(frontArgs) and apply(backArgs))
            return BoolLit(false)
        elif symbolName == 'procedure?':
            return BoolLit(arg1.isProcedure)
        elif symbolName == 'display':
            return arg1
        elif symbolName == 'newline':
            return StrLit("", false)
        elif symbolName == 'exit' or symbolName == 'quit':
            exit()
        elif symbolName == 'write':
            arg1.print(0)
        elif symbolName == 'eval':
            return arg1
        elif symbolName == 'apply':
            return arg1.apply(arg2)
        elif symbolName == 'read':
            parser = Parser()
            return parser.parseExp()
        elif symbolName == 'interaction-environment':
            self.env.print(0)
        else:
            arg1.print(0)
            return Nil()
        return StrLit('>')
Exemplo n.º 9
0
 def eval(self, exp, env):
     return StrLit("eval for this special has not been defined")
Exemplo n.º 10
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(">")
Exemplo n.º 11
0
 def eval(self, exp, env):
     key = exp.getCdr().getCar()
     val = exp.getCdr().getCdr().getCar()
     if key.isSymbol():
         env.assign(key,val)
     return StrLit("no values returned")