public static ArrayList<Node> execute(Node node) {
        ArrayList<Node> results = new ArrayList<Node>();

        // If defining a constant, then add it to the runtime stack. If defining a procedure, do nothing.
        if (node.getToken() != null && node.getToken().getType() == TokenType.KW_DEFINE) {
            String variableId = node.getCdr().getToken().getText(); // Get name of variable
            SymTabEntry entry = symTabStack.lookup(variableId); // Get corresponding SymTabEntry
            Node variable = (Node) entry.get(Attribute.VARIABLE_NODE);
            SymTabEntry newEntry = runTimeStack.enterLocal(variableId);

            // Go into this block to determine if the variable refers to a procedure or constant
            if (variable != null) {
                entry = getVariableType(variable);
            }

            newEntry.putAll(entry); // Copy the Attributes from the original SymTabEntry
        }
        // Execute if define is not the CAR of the list. This also means it is a procedure call.
        else {
            Node root = updateRunTimeEnvironment(node);

            // Note that we are getting the CDR twice. When running built in functions, manually
            // create these inside processResult()
            executeProcedure(root.getCdr().getCdr(), results);

            // Relink runtime stack and runtime display
            SymTab symTab = runTimeStack.pop();
            int level = symTab.getNestingLevel();
            SymTab predecessor = runTimeStack.getPredecessor(level);

            if (predecessor != null) {
                runTimeDisplay.set(level, predecessor);
            }
            else {
                runTimeDisplay.pop();
            }

            // If current nesting level = 1, then the top level list has finished executing, so print it
            if (runTimeStack.getCurrentNestingLevel() == 1) {
                System.out.println("\n*** Results ***\n");

                for (Node resultNode : results) {
                    if (resultNode.getToken() != null && resultNode.getToken().getType() == TokenType.SS_QUOTE) {
                        resultNode = resultNode.getCdr();
                    }

                    // If the token is null, then this is a list.
                    if (resultNode.getToken() == null) {
                        new TreePrinter().printList(resultNode.getCar(), 0);
                    }
                    else {
                        System.out.print(resultNode.getToken().getText());
                    }
                }

                System.out.println("");
            }
        }

        return results;
    }