Submit at least 100 lines total of test code in two email messages to sakumar@copper with subjects accept2 and reject2, including cases that the reader should accept and reject, respectively. Submit your project by email to sakumar@copper with subject code2.
Bundy is an alternative syntax for Scheme. It roughly follows the Algol syntactic tradition, which includes better known grammars such as those of Pascal and Ada.
Non-terminals are indicated by italics. A number is as defined in Project 1. String, character, boolean, and variable are as defined in the R4RS, except that the syntactic keywords (which cannot be variables) are begin, end, define, lambda, let, in, cond, =>, else, <-, :=, ?, hd, and tl. As in Scheme, whitespace must separate tokens that might be confused for a longer token if concatinated. Thus x?3 is a variable, while x ? 3 is an "eq?" expression.
program --> begin definition-list , expression end
definition-list --> definition | definition , definition-list
definition --> define variable expression
expression --> lambda ( formals ) expression
expression --> let variable bindings in expression
expression --> let bindings in expression
expression --> cond cond-clause-list
expression --> variable := expression
expression --> expression ? expression
expression --> expression . expression
expression --> ? expression
expression --> expression hd
expression --> expression tl
expression --> expression ( actuals )
expression --> ( expression-list )
expression --> variable
expression --> literal
formals --> # | variable-list
variable-list --> variable | variable , variable-list
bindings --> # | binding-list
binding-list --> binding | binding , binding-list
binding --> variable <- expression
cond-clause-list --> cond-clause | cond-clause else cond-clause-list
cond-clasue --> expression => expression
actuals --> # | expression-list
expression-list --> expression | expression , expression-list
literal --> boolean | number | character | string
The infix operators := and . are right-associateive, while the infix operaators ? and application are left-associative. An else clause is associated with the nearest possible cond expression.
T[[begin e_1 , .1. , e_n end]] ==> (begin T[[e_1]] .1. T[[e_n]] )
T[[define id e]] ==> (define id T[[e]] )
T[[lambda ( id_1 , ... , id_n) e]] ==> (lambda ( id_1 ... id_n ) T[[e]] )
T[[let id id_1<- , ... , id_n<-e_n in e]] ==> (let id (( id_1 T[[e_1]] ) ... ( id_n T[[e_n]] )) T[[e]] )
T[[let id_1<- , ... , id_n<-e_n in e]] ==> (let (( id_1 T[[e_1]] ) ... ( id_n T[[e_n]] )) T[[e]] )
T[[cond p_1 => e_1 else .1. else p_n => e_n]] ==> (cond ( T[[p_1]] T[[e_1]] ) .1. ( T[[p_n]] T[[e_n]] ))
T[[id := e]] ==> (begin (set! id T[[e]] ) id )
T[[e_1 ? e_2]] ==> (eq? T[[e_1]] T[[e_2]] )
T[[e_1 . e_2]] ==> (cons T[[e_1]] T[[e_2]] )
T[[? e]] ==> (null? T[[e]] )
T[[e hd]] ==> (car T[[e]] )
T[[e tl]] ==> (cdr T[[e]] )
T[[e_0 ( e_1 , ... , e_n )]] ==> ( T[[e_0]] T[[e_1]] ... T[[e_n]] )
T[[( e )]] ==> T[[e]]
T[[( e_1 , .2. , e_n )]] ==> (begin T[[e_1]] .2. T[[e_n]] )
T[[variable]] ==> variable
T[[literal]] ==> literal
begin
define reverse
lambda (x)
reverse-help(x , list()) ,
define reverse-help
lambda (x , a)
cond
? x => a
else
#t => reverse-ehlp(x tl , x hd . a) ,
define ans 1 . 2 . 3 . list() ,
ans := reverse(ans)
end
is equivalent to the Scheme program
(begin
(define reverse
(lambda (x)
(reverse-help x (list))))
(define reverse-help
(lambda (x a)
(cons
((null? x) a)
(#t (reverse-help (cdr x)
(cons (car x) a))))))
(define ans
(cons 1 (cons 2 (cons 3 (list)))))
(begin (set! ans (reverse ans)) ans))