Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

/prog/ challenge n+1: My other car

Name: Anonymous 2021-03-26 16:54

The goal

The goal is to implement LISP's car/cdr[1] family of functions. Write a program that receives two inputs on the standard input, separated by spaces: the first (cudder) is an accessor in the form of ``c[ad]{0,32}r''. The second is a LISP-style sexp[2], containing integers, potentially nested. Your program should execute the cudder on the sexp and print the result to standard output.

Assumptions

* The cudder will always be provided in such a way that the result is non-NIL/non-NuRuPo.
* Maximum nesting level is 8 levels deep.

Examples

./cudder cdr "(1 2 3 4)"
(2 3 4)
./cudder car "(1 2 3 4)"
1
./cudder cddr "(1 2 3 4)"
(3 4)
./cudder cdddr "(1 2 3 4)"
(4)
./cudder cadr "(1 2 3 4)"
2
./cudder car "((1) 2 3 4)"
(1)
./cudder caar "((1) 2 3 4)"
1
./cudder cadr "(1 (2 3 4))"
(2 3 4)


[1] https://en.wikipedia.org/wiki/CAR_and_CDR
[2] https://en.wikipedia.org/wiki/S-expression#Use_in_Lisp

Name: Anonymous 2021-03-28 4:47

new and improved
#include<stdio.h>
#include<ctype.h>

#define DECL(ret, name, ...) \
struct name { \
ret (*f)(struct name *,__VA_ARGS__); \
void *p; \
}

#define CALL(closure, ...) closure.f(&closure,__VA_ARGS__)

DECL(int,ii,int);

int nothing(int c){
return 0;
}

struct callf{
int (*f)(int);
};

int callf(struct ii *closure, int c){
struct callf *p=closure->p;
return p->f(c);
}

struct addspace{
int flag;
struct ii act;
};

int addspace(struct ii *closure, int c){
struct addspace *p=closure->p;
if(p->flag){
p->flag=0;
CALL(p->act,' ');
}
return CALL(p->act,c);
}

const struct ii myisdigit={callf,&(struct callf){isdigit}};
const struct ii myisspace={callf,&(struct callf){isspace}};
const struct ii mynothing={callf,&(struct callf){nothing}};

int satisfy(struct ii check, struct ii act){
int c;
int i=0;
while((c=getchar())!=EOF)
if(!CALL(check,c)){
ungetc(c,stdin);
break;
}else{
++i;
CALL(act,c);
}
return i;
}

int expect1(int x){
int c=getchar();
if (x==c)
return 1;
else{
ungetc(c, stdin);
return 0;
}
}

int elementloop(struct ii act1, struct ii act2);
int element(struct ii act1, struct ii act2){
if(expect1(')')){
CALL(act1,')');
return 0;
} else if(expect1('(')){
CALL(act2,'(');
satisfy(myisspace,mynothing);
return elementloop(act1,act2);
} else
satisfy(myisdigit,act2);
return 1;
}

int elementloop(struct ii act1, struct ii act2){
struct addspace addspaceinfo={1,act2};
struct ii myaddspace={addspace,&addspaceinfo};
if(element(act1,act2))
do{
satisfy(myisspace,mynothing);
addspaceinfo.flag=1;
}while(element(act1,myaddspace));
return 1;
}

int main(int argc, char *argv[]){
int status;
const struct ii myputchar={callf,&(struct callf){putchar}};
argv[1]++; /* c */
expect1('(');
while(*argv[1]!='r'){
satisfy(myisspace,mynothing);
switch(*argv[1]++){
case 'd':
element(mynothing,mynothing);
status=0;
break;
case 'a':
if(expect1('('))
status=1;
else{
satisfy(myisdigit,myputchar);
status=2;
}
}
}
if(!status){
satisfy(myisspace,mynothing);
putchar('(');
elementloop(myputchar,myputchar);
}
else if(status==1){
ungetc('(',stdin);
element(myputchar,myputchar);
}
putchar('\n');
}
Edited on 28/03/2021 05:01.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List