我已经实现了语言“ ROL”,现在我正试图扩展该语言以支持fun,并称呼我正在尝试在替代模型中实现它。
这是我的eval函数代码(请注意,此代码在没有乐趣和调用的情况下也可以正常工作。因此,这两个实现一定是问题所在
(: eval : RegE -> RES)
;; evaluates RegE expressions by reducing them to bit-lists
(define (eval expr)
(cases expr
[(Reg right) (RegV right)]
[(Bool b) (RES_Bool b)]
[(Id name) (error 'eval "free identifier: ~s" name)]
[(And left right) (reg-arith-op bit-and (eval left ) (eval right) )]
[(Or left right) (reg-arith-op bit-or (eval left ) (eval right) )]
[(Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))]
[(Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))]
[(Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))]
[(With bound-id named-expr bound-body)
(eval (subst bound-body
bound-id
(Reg (RegV->bit-list(eval named-expr)))))]
[(Fun bound-id bound-body) expr]
[(Call fun-expr arg-expr)
(let ([fval (eval fun-expr)])
(cases fval
[(Fun bound-id bound-body)
(eval (subst bound-body
bound-id
(eval arg-expr)))]
[else (error 'eval "`call' expects a function, got: ~s"
fval)]))]
[(If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))]
))
这是我最聪明的功能:
(define (subst expr from to)
(cases expr
[(Reg g) expr]
[(Bool g) expr]
[(And left right)(And (subst left from to)(subst right from to))]
[(Or left right)(Or (subst left from to)(subst right from to))]
[(If bool ifBody elseBody) (If (subst bool from to) (subst ifBody from to) (subst elseBody from to))]
[(Maj left)(Maj (subst left from to))]
[(Geq left right)(Geq (subst left from to)(subst right from to))]
[(Shl left)(Shl (subst left from to))]
[(Id name) (if (eq? name from) to expr)]
[(With bound-id named-expr bound-body)
(if (eq? bound-id from)
expr
(With bound-id
named-expr
(subst bound-body from to)))]
[(Call left right) (Call (subst left from to) (subst right from to))]
[(Fun bound-id bound-body)
(if (eq? bound-id from)
expr
(Fun bound-id (subst bound-body from to)))]))
我遇到了错误:
Type Checker: type mismatch
expected: RegE
given: RES in: fval
. Type Checker: type mismatch
expected: RegE
given: RES in: (eval arg-expr)
. Type Checker: type mismatch
expected: RES
given: Fun in: (cases expr ((Reg right) (RegV right)) ((Bool b) (RES_Bool b)) ((Id name) (error (quote eval) "free identifier: ~s" name)) ((And left right) (reg-arith-op bit-and (eval left) (eval right))) ((Or left right) (reg-arith-op bit-or (eval left) (eval right))) ((Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))) ((Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))) ((Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))) ((With bound-id named-expr bound-body) (eval (subst bound-body bound-id (Reg (RegV->bit-list (eval named-expr)))))) ((Fun bound-id bound-body) expr) ((Call fun-expr arg-expr) (let ((fval (eval fun-expr))) (cases fval ((Fun bound-id bound-body) (eval (subst bound-body bound-id (eval arg-expr)))) (else (error (quote eval) "`call' expects a function, got: ~s" fval))))) ((If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))))
. Type Checker: Summary: 3 errors encountered in:
fval
(eval arg-expr)
(cases expr ((Reg right) (RegV right)) ((Bool b) (RES_Bool b)) ((Id name) (error (quote eval) "free identifier: ~s" name)) ((And left right) (reg-arith-op bit-and (eval left) (eval right))) ((Or left right) (reg-arith-op bit-or (eval left) (eval right))) ((Shl E1) (RegV (shift-left (RegV->bit-list (eval E1))))) ((Maj E1) (RES_Bool (majority? (RegV->bit-list (eval E1))))) ((Geq E1 E2) (RES_Bool (geq-bitlists? (RegV->bit-list (eval E1)) (RegV->bit-list (eval E2))))) ((With bound-id named-expr bound-body) (eval (subst bound-body bound-id (Reg (RegV->bit-list (eval named-expr)))))) ((Fun bound-id bound-body) expr) ((Call fun-expr arg-expr) (let ((fval (eval fun-expr))) (cases fval ((Fun bound-id bound-body) (eval (subst bound-body bound-id (eval arg-expr)))) (else (error (quote eval) "`call' expects a function, got: ~s" fval))))) ((If E1 E2 E3) (if (RegV->boolean (eval E1)) (eval E2) (eval E3))))
>
我的数据类型是:
(define-type RegE
[Reg Bit-List]
[Xor RegE RegE]
[And RegE RegE]
[Or RegE RegE]
[Shl RegE]
[Id Symbol]
[With Symbol RegE RegE]
[Bool Boolean]
[Geq RegE RegE]
[Maj RegE]
[If RegE RegE RegE]
[Fun Symbol RegE]
[Call RegE RegE])
和:
(define-type RES
[RES_Bool Boolean]
[RegV Bit-List])
我可以看到,对于(let ([fval (eval fun-expr)
而言,(eval fun-expr)
会返回RES,我想这可能是问题所在,还有其他方法可以解决吗?任何帮助将不胜感激..
答案 0 :(得分:1)
关键问题是如何在运行时表示函数。
eval
的定义是:
(: eval : RegE -> RES)
;; evaluates RegE expressions by reducing them to bit-lists
(define (eval expr)
(cases expr
...
[(Fun bound-id bound-body) expr]
...
评估(Fun bound-id bound-body)
的结果必须是RES。
也许将RES扩展为:
(define-type RES
[RES_Bool Boolean]
[RegV Bit-List]
[FunV Symbol RegE])
然后让eval
返回一个(FunV bound-id bound-body)
。
在“通话”评估中,您将需要切换到
(cases fval
[(FunV bound-id bound-body)
因为fval
是RES。