%{ #import "SchemeTypes.h" #define YYSTYPE id YYSTYPE yyresult; int yyinputitem; id yyresultform; extern int yysofar; extern NSMutableArray *positionStack; %} %token LPAREN %token LVECTPAREN %token RPAREN %token DEFINE %token SET %token LAMBDA %token BEGINTOK %token AND %token OR %token CASE %token COND %token ELSE %token ARROW %token CALLCC %token APPLY %token IF %token LET %token LETSTAR %token LETREC %token DOT %token INTEGER %token CHAR %token BOOLEAN %token DOUBLE %token SYMBOL %token STRING %token QUOTECHAR %token QUOTE %% top: /* empty */ { $$ = [NSNull null]; yyresultform = $$; } | topitem top { $$ = [Triple newTag:FORM_TOP Arg1:$1 Arg2:$2]; yyresultform = $$; yyinputitem++; } ; topitem: LPAREN DEFINE SYMBOL form RPAREN { NSValue *entry = [NSValue valueWithRange:NSMakeRange(yysofar, 0)]; $$ = [Triple newTag:FORM_DEFINE1 Arg1:$3 Arg2:$4]; [[positionStack lastObject] addObject:entry]; } | LPAREN DEFINE nonemptysymlist sequence RPAREN { NSValue *entry = [NSValue valueWithRange:NSMakeRange(yysofar, 0)]; $$ = [Triple newTag:FORM_DEFINE2 Arg1:$3 Arg2:$4]; [[positionStack lastObject] addObject:entry]; } | form { NSValue *entry = [NSValue valueWithRange:NSMakeRange(yysofar, 0)]; $$ = $1; [[positionStack lastObject] addObject:entry]; } ; sequence: form { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | form sequence { $$ = [Pair newCar:$1 Cdr:$2]; } ; revsequence: form { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | revsequence form { $$ = [Pair newCar:$2 Cdr:$1]; } ; qform: INTEGER { $$ = $1; } | CHAR { $$ = $1; } | BOOLEAN { $$ = $1; } | DOUBLE { $$ = $1; } | SYMBOL { $$ = $1; } | STRING { $$ = $1; } | qlist { $$ = $1; } | qvector { $$ = $1; } | QUOTECHAR qform { $$ = [Pair newCar:[[Symbol alloc] initSCMSymbol:"quote"] Cdr:[Pair newCar:$2 Cdr:[NSNull null]]]; } | ARROW { $$ = [[Symbol alloc] initSCMSymbol:"=>"]; } | QUOTE { $$ = [[Symbol alloc] initSCMSymbol:"quote"]; } | CALLCC { $$ = [[Symbol alloc] initSCMSymbol:"call-with-current-continuation"]; } | APPLY { $$ = [[Symbol alloc] initSCMSymbol:"apply"]; } | DEFINE { $$ = [[Symbol alloc] initSCMSymbol:"define"]; } | SET { $$ = [[Symbol alloc] initSCMSymbol:"set!"]; } | LAMBDA { $$ = [[Symbol alloc] initSCMSymbol:"lambda"]; } | IF { $$ = [[Symbol alloc] initSCMSymbol:"if"]; } | BEGINTOK { $$ = [[Symbol alloc] initSCMSymbol:"begin"]; } | AND { $$ = [[Symbol alloc] initSCMSymbol:"and"]; } | OR { $$ = [[Symbol alloc] initSCMSymbol:"or"]; } | CASE { $$ = [[Symbol alloc] initSCMSymbol:"case"]; } | COND { $$ = [[Symbol alloc] initSCMSymbol:"cond"]; } | ELSE { $$ = [[Symbol alloc] initSCMSymbol:"else"]; } | LET { $$ = [[Symbol alloc] initSCMSymbol:"let"]; } | LETSTAR { $$ = [[Symbol alloc] initSCMSymbol:"let*"]; } | LETREC { $$ = [[Symbol alloc] initSCMSymbol:"letrec"]; } ; form: INTEGER { $$ = $1; } | CHAR { $$ = $1; } | BOOLEAN { $$ = $1; } | DOUBLE { $$ = $1; } | SYMBOL { $$ = $1; } | STRING { $$ = $1; } | list { $$ = $1; } | vector { $$ = $1; } | lambda { $$ = $1; } | if { $$ = $1; } | let { $$ = $1; } | letstar { $$ = $1; } | letrec { $$ = $1; } | quote { $$ = $1; } | apply { $$ = $1; } | set { $$ = $1; } | begin { $$ = $1; } | and { $$ = $1; } | or { $$ = $1; } | case { $$ = $1; } | cond { $$ = $1; } | callcc { $$ = $1; } ; callcc: LPAREN CALLCC form RPAREN { $$ = [Triple newTag:FORM_CALLCC Arg1:$3]; } ; singlecase: LPAREN LPAREN sequence RPAREN sequence RPAREN { $$ = [Pair newCar:$3 Cdr:$5]; } ; singlecond: LPAREN form RPAREN { $$ = [Triple newTag:FORM_SCOND1 Arg1:$2]; } | LPAREN form sequence RPAREN { $$ = [Triple newTag:FORM_SCOND2 Arg1:$2 Arg2:$3]; } | LPAREN form ARROW form RPAREN { $$ = [Triple newTag:FORM_SCOND3 Arg1:$2 Arg2:$4]; } ; elsecasecond: LPAREN ELSE sequence RPAREN { $$ = [Pair newCar:[NSNull null] Cdr:$3]; } ; cases: singlecase { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | cases singlecase { $$ = [Pair newCar:$2 Cdr:$1]; } ; conditions: singlecond { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | conditions singlecond { $$ = [Pair newCar:$2 Cdr:$1]; } ; case: LPAREN CASE form cases RPAREN { $$ = [Triple newTag:FORM_CASE Arg1:$3 Arg2:$4]; } | LPAREN CASE form cases elsecasecond RPAREN { $$ = [Triple newTag:FORM_CASE Arg1:$3 Arg2:[Pair newCar:$5 Cdr:$4]]; } ; cond: LPAREN COND conditions RPAREN { $$ = [Triple newTag:FORM_COND Arg1:$3]; } | LPAREN COND conditions elsecasecond RPAREN { $$ = [Triple newTag:FORM_COND Arg1:[Pair newCar:$4 Cdr:$3]]; } ; and: LPAREN AND revsequence RPAREN { $$ = [Triple newTag:FORM_AND Arg1:$3]; } | LPAREN AND RPAREN { $$ = [Triple newTag:FORM_AND Arg1:[NSNull null]]; } ; or: LPAREN OR revsequence RPAREN { $$ = [Triple newTag:FORM_OR Arg1:$3]; } | LPAREN OR RPAREN { $$ = [Triple newTag:FORM_OR Arg1:[NSNull null]]; } ; begin: LPAREN BEGINTOK sequence RPAREN { $$ = [Triple newTag:FORM_BEGIN Arg1:$3]; } ; set: LPAREN SET SYMBOL form RPAREN { $$ = [Triple newTag:FORM_SET Arg1:$3 Arg2:$4]; } ; apply: LPAREN APPLY form form RPAREN { $$ = [Triple newTag:FORM_APPLY Arg1:$3 Arg2:$4]; } ; if: LPAREN IF form form RPAREN { $$ = [Triple newTag:FORM_IF1 Arg1:$3 Arg2:$4]; } | LPAREN IF form form form RPAREN { $$ = [Triple newTag:FORM_IF2 Arg1:$3 Arg2:$4 Arg3:$5]; } ; lambda: LPAREN LAMBDA SYMBOL sequence RPAREN { $$ = [Triple newTag:FORM_LAMBDA1 Arg1:$3 Arg2:$4]; } | LPAREN LAMBDA symlist sequence RPAREN { $$ = [Triple newTag:FORM_LAMBDA2 Arg1:$3 Arg2:$4]; } ; quote: QUOTECHAR qform { $$ = [Triple newTag:FORM_QUOTE Arg1:$2]; } | LPAREN QUOTE qform RPAREN { $$ = [Triple newTag:FORM_QUOTE Arg1:$3]; } ; singlebinding: LPAREN SYMBOL form RPAREN { $$ = [Triple newTag:FORM_BINDING Arg1:$2 Arg2:$3]; } ; listofbindings: singlebinding { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | singlebinding listofbindings { $$ = [Pair newCar:$1 Cdr:$2]; } ; let: LPAREN LET LPAREN listofbindings RPAREN sequence RPAREN { $$ = [Triple newTag:FORM_LET Arg1:$4 Arg2:$6]; } ; letstar: LPAREN LETSTAR LPAREN listofbindings RPAREN sequence RPAREN { $$ = [Triple newTag:FORM_LETSTAR Arg1:$4 Arg2:$6]; } ; letrec: LPAREN LETREC LPAREN listofbindings RPAREN sequence RPAREN { $$ = [Triple newTag:FORM_LETREC Arg1:$4 Arg2:$6]; } ; emptylist: LPAREN RPAREN { $$ = [NSNull null]; } ; nonemptylistdata: form { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | form DOT form { $$ = [Pair newCar:$1 Cdr:$3]; } | form nonemptylistdata { $$ = [Pair newCar:$1 Cdr:$2]; } ; qnonemptylistdata: qform { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | qform DOT qform { $$ = [Pair newCar:$1 Cdr:$3]; } | qform qnonemptylistdata { $$ = [Pair newCar:$1 Cdr:$2]; } ; nonemptyvectdata: form { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | form nonemptyvectdata { $$ = [Pair newCar:$1 Cdr:$2]; } ; qnonemptyvectdata: qform { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | qform qnonemptyvectdata { $$ = [Pair newCar:$1 Cdr:$2]; } ; nonemptylist: LPAREN nonemptylistdata RPAREN { $$ = $2; } ; qnonemptylist: LPAREN qnonemptylistdata RPAREN { $$ = $2; } ; list: nonemptylist { $$ = $1; } | emptylist { $$ = $1; } ; qlist: qnonemptylist { $$ = $1; } | emptylist { $$ = $1; } ; vector: LVECTPAREN nonemptyvectdata RPAREN { $$ = [Vector newFromList:$2]; } | LVECTPAREN RPAREN { $$ = [Vector newFromList:(Pair *)[NSNull null]]; } ; qvector: LVECTPAREN qnonemptyvectdata RPAREN { $$ = [Vector newFromList:$2]; } | LVECTPAREN RPAREN { $$ = [Vector newFromList:(Pair *)[NSNull null]]; } ; nonemptysymlistdata: SYMBOL { $$ = [Pair newCar:$1 Cdr:[NSNull null]]; } | SYMBOL DOT SYMBOL { $$ = [Pair newCar:$1 Cdr:$3]; } | SYMBOL nonemptysymlistdata { $$ = [Pair newCar:$1 Cdr:$2]; } ; nonemptysymlist: LPAREN nonemptysymlistdata RPAREN { $$ = $2; } ; symlist: nonemptysymlist { $$ = $1; } | emptylist { $$ = $1; } ; %%