/*
For this program you will implement a very small subset of the LISP
programming language using singly-linked lists. You may write your code
in C or C++. In addition to correctness, programming style is also
important, so
please write modular, well-documented code.

LISP stands for ``list processing'' and is used to define, query and
modify
lists of symbols. For us, a symbol is a string of no more than 32
uppercase
alphanumeric characters (A-Z, 0-9). A list is denoted by a
space-separated
sequence of symbols surrounded by parentheses, e.g., ( CSE 2320 SECTION
501
), with one space between each symbol and surrounding parentheses. The
empty
list is denoted by ( ).

The three LISP commands you are to implement are SETF, NTH and NTHREST
as
described in the following table, where n is a positive integer less
than
100.

                                       Sets variable var to list for
 ( SETF var list )                     possible future reference.
Variable
                                       var can be any valid symbol. SETF
                                      returns the list.

                                       Returns the nth symbol in the
given
                                       list or the list stored in
variable
                                       var. If the list has fewer than n
( NTH n [$\{list \vert var\}$] )      elements, then NTH returns the
empty
                                       list ( ). If the variable var is
                                      undefined, then NTH returns
``Error:
                                       undefined variable''.

                                       Returns the list remaining after
                                      removing the first n symbols from
                                      the given list or the list stored
in
                                       variable var. If the list has
fewer
 ( NTHREST n [$\{list \vert var\}$] )  than n symbols, then NTHREST
returns
                                       the empty list ( ). If the
variable
                                       var is undefined, then NTHREST
                                       returns ``Error: undefined
                                       variable''.



1.   Implement data structures for the singly-linked list used to store
the
     lists of symbols.

2.   You may implement a global array to store the variables, but this
is
     the only global variable allowed. There will be no more than 100
     different vairables.

3.   Be sure to garbage-collect the existing list when a variable is
     redefined. Garbage-collect all lists allocated just for NTH and
NTHREST
     commands. Before ending the program, garbage-collect all other
     allocated memory.

4.   The main part of your program will read in data from a file whose
name
     is given as the first argument to your executable. The file will
     consist of one or more lines, each containing a valid command from
    among the three described above. Your main program should process
each
     line one at a time and for each line, output the command read in,
the
     result and a newline.
*/
/*name:Anan Tongprasith*/
/*compile: cc sll.c*/

#include 
#include 

/* A new structure type is defined as "mylist":			*/ 
/*	(	name,	pointer		)		.	*/

/* A global array named "namelist" is defined as type "mylist".	*/
/*--------------------------------------------------------------*/
/*	Place in array|	variable names|	pointer			*/
/*--------------------|---------------|-------------------------*/
/*	namelist[0]   |	    X	      | pointer-to-X-head 	*/
/*	namelist[1]   |	    Y         |	pointer-to-Y-head 	*/
/*	     :	      |	    :         |	   :			*/
/*	namelist[99]  |	   DOE        |	pointer-to-DOE-head	*/
/*--------------------------------------------------------------*/

/* A variable is linked to a singly linked-list:		*/
/*	namelist[0]		namelist[1]			*/
/*	X:head-ptr		Y:head-ptr			*/
/*	   |							*/
/*	  \|/							*/
/*	X(1):nextptr--->X(2):nextptr--->...--->X(n):0		*/

/* Main function reads command from a file, calls functions,	 */
/* and clear the variable array.				 */
/* Function "mysetf" carries on the "SETF" command.		*/
/* Function "mynth" carries on the "NTH" command.		*/
/* Function "mynthrest" carries on the "NTHREST" command.	*/
/* Function "myfree" frees the memory blocks allocated for a 	*/
/* 	linked-list, given the head of the list.		*/
/* Function "findplace" find the location of the specified variable */
/*	from the "namelist" array. If it isn't found, a new available*/
/*	location is returned (for a new variable).*/

/* Define a new structure data type*/
struct mylist{
   		char *myname;
		struct mylist *next;
  };
/*Array of variables'names and head-ptr's of the linked-lists */
struct mylist *namelist[100];

int main(int argc, char *argv[])
{ struct mylist *info,*nextinfo;
  char mycommand[10],myparam[5],buf[100],newline[100];
  int mycount;long i;FILE *fp;
/* Initialize the "namelist" array */
	for(mycount=0;mycount<100;mycount++)
        {	
/* 2 pointers need 16 bytes */
		namelist[mycount]=malloc(16);
		namelist[mycount]->myname=malloc(8);
/* Put an empty string into every name */
		sprintf(namelist[mycount]->myname,"%s","\0");
		namelist[mycount]->next=0;
	}
	fp=fopen(argv[1],"r");
/* Read the lines */
	while(fgets(newline,100,fp) != NULL)
	{	
/* Read in command and parameters */
		sscanf(newline,"( %s %s %s",mycommand,myparam,buf);	
/* Reread if the final parameter is a list */
		if(strcmp(buf,"(")==0)
		   sscanf(newline,"( %s %s %100c",mycommand,myparam,buf);
/* Checking which function to run*/
printf("%s",newline);
		if(strcmp(mycommand,"SETF")==0)
			mysetf(myparam,buf);
		if(strcmp(mycommand,"NTH")==0)
			mynth(atoi(myparam),buf);
		if(strcmp(mycommand,"NTHREST")==0)
			mynthrest(atoi(myparam),buf);
	}
/* Clear all the variables, free memory blocks, and exit */
		for(mycount=0;mycount<100;mycount++)
		{
			if(strlen(namelist[mycount]->myname)!=0)
/* Clear every available variable in the array */
				myfree(namelist[mycount]->next);
/* Clear the array itself */
			free(namelist[mycount]);
			free(namelist[mycount]->myname);
			free(namelist[mycount]->next);
		}
	
	fclose(fp);
}

int mysetf(char *myparam,char *mybuf)
{ struct mylist *info,*newinfo;
  int myplace=0;
  char myvalue[100]="a",mynewbuf[100]="a";
/* Find available place in the "namelist" array */
/* New variable is given a new place. Old variable is given the old one.*/
	myplace=findplace(myparam);
/* Clear the old one (if exists) first */
	myfree(namelist[myplace]->next);
/* Adding a new list */
	  sscanf(mybuf,"( %s %100c",myvalue,mynewbuf);
	  strcpy(mybuf,mynewbuf);
/* First entry */
/* 16 bytes for 2 pointers */
	  info=malloc(16);
/* Put the variable name in */
	  sprintf(namelist[myplace]->myname,"%s",myparam);
/* Put the head pointer in */
	  namelist[myplace]->next=info;
/* First entry of the linked-list */
	  info->myname=malloc(strlen(myvalue)+1);
	  sprintf(info->myname,"%s",myvalue);
	  sscanf(mybuf,"%s %100c",myvalue,mynewbuf);
	  strcpy(mybuf,mynewbuf);
/* Keep adding untill end of the list ")" */
	  while(strcmp(myvalue,")")!=0)
	  {	newinfo=malloc(16);
		info->next=newinfo;
		info=newinfo;
		info->myname=malloc(strlen(myvalue)+1);
		strcpy(info->myname,myvalue);
		sscanf(mybuf,"%s %100c",myvalue,mynewbuf);
		strcpy(mybuf,mynewbuf);
	  }
	  info->next=0;
/* Printing out a new variable's */
	printf("( ");	
	info=namelist[myplace]->next;
	do
	{	printf("%s ",info->myname);
		info=info->next;
	}
	while(info!=0);
	printf(")\n\n");
}
int findplace(char *myparam)
{ int mycount=0,myplace=0;
/* Searching until finding an empty one */
	  while(strlen(namelist[mycount]->myname)!=0&&mycount<100)
	  {
/* Return the location we found the variable */
		if(strcmp(namelist[mycount]->myname,myparam)==0)
		{	
			return mycount;	
		}
		else
		{	mycount++;
		}
	  }	
/* The variable isn't found, return a new place in the "namelist" */
	return mycount;
}
int mynth(int n,char *buf)
{  struct mylist *info,*newinfo,*head;
   char newbuf[100],myvalue[30];
   int mycount=1,myclear=0;
	if(buf[0]=='(')
/* A list is passed in, let's put it into a linked-list */
	{ sscanf(buf,"( %s %100c",myvalue,newbuf);
	  strcpy(buf,newbuf);
/* Clearing flag is set, the linked-list will be cleared later */
	  myclear=1;
	  while(strcmp(myvalue,")")!=0) 
	  {	
		newinfo=malloc(16);
		if(mycount==1)	
			{	head=newinfo;
				info=head;
			}
		else	{	info->next=newinfo;
				info=newinfo;
			}
		info->myname=malloc(strlen(myvalue)+1);
		sprintf(info->myname,"%s",myvalue);
		sscanf(buf,"%s %100c",myvalue,newbuf);
		strcpy(buf,newbuf);
		mycount++;
	  }
	  info->next=0;
	}
/* A variable is passed in, look up the table first */
	else
	{	mycount=findplace(buf);
/* Check if it is a new place (string length=0) or not */
		if(strlen(namelist[mycount]->myname)==0)
/* Findplace give you a new place, that means it can't find the variable*/
		{	printf("Error: undefined variable\n\n");
			return 0;
		}
		else
/* The variable is found */
			head=namelist[mycount]->next;
	}
/* Printing output */
	mycount=1;info=head;
/* Skip (n-1) steps */
	while(mycountnext;
		info=newinfo;
		mycount++;
	}

	if(head==0||info==0)	printf("( )\n\n");
/* Printing the nth */
	else		printf("%s\n\n",info->myname);	
/* If clearflag is set, clear the memory on temp variable */
	if(myclear!=0)
		myfree(head);
}
int mynthrest(int n,char *buf)
{  struct mylist *info,*newinfo,*head;
   char newbuf[100],myvalue[30];
   int mycount=1,myclear=0;
	if(buf[0]=='(')
/* A list is passed in, let's put it into a linked-list */
	{ sscanf(buf,"( %s %100c",myvalue,newbuf);
	  strcpy(buf,newbuf);
/* A clearflag is set */
	  myclear=1;
	  while(strcmp(myvalue,")")!=0)
	  {	
		newinfo=malloc(16);
		if(mycount==1)	
			{	head=newinfo;
				info=head;
			}
		else	{	info->next=newinfo;
				info=newinfo;
			}
		info->myname=malloc(strlen(myvalue)+1);
		sprintf(info->myname,"%s",myvalue);
		sscanf(buf,"%s %100c",myvalue,newbuf);
		strcpy(buf,newbuf);
		mycount++;
	  }
	  info->next=0;
	}
/* A variable is passed in, look up the table first */
	else
	{	mycount=findplace(buf);
		if(strlen(namelist[mycount]->myname)==0)
/* Findplace give you a new place, that means it can't find the variable*/
		{
			printf("Error: undefined variable\n\n");
			return 0;
		}
		else
/* The variable is found */
			head=namelist[mycount]->next;
	}
/* Printing output */
	mycount=1;info=head;
/* Skipping the first n items */
	while(mycount<=n&&info!=0)
	{	
		newinfo=info->next;
		info=newinfo;
		mycount++;
	}
	printf("( ");
	while(info!=0)
	{	newinfo=info->next;
		printf("%s ",info->myname);
		info=newinfo;
	}
	printf(")\n\n");
/* Clear memory on temp variable */
	if(myclear!=0)
	{	myfree(head);
	}
}
/* Free the memory blocks, given the head of the list */
int myfree(struct mylist *myinfo)
{  struct mylist *newinfo;
/* Repeat until the end of the list */
	while(myinfo!=0)	
	{	newinfo=myinfo->next;
		free(myinfo);
		free(myinfo->myname);
		free(myinfo->next);
		myinfo=newinfo;
	}
	return 0;
}

    Source: geocities.com/Vienna/7079/src

               ( geocities.com/Vienna/7079)                   ( geocities.com/Vienna)