Added TidBIT

This commit is contained in:
2026-01-09 13:06:08 -05:00
parent 5be8bba895
commit a465917f36
3 changed files with 154 additions and 87 deletions
+2 -87
View File
@@ -272,8 +272,8 @@ CFG for the BARF language:
(if (string=? name fname) (f) (#f))])))]))
(if (not foundfun) (error 'findfun "Function not found.") foundfun))
(: eval : BARF -> Primitive)
;; evaluates BARF expressions by reducing them to numbers
(: eval : PROGRAM -> Primitive)
;; evaluates PROGRAM expressions by reducing them to numbers
(define (eval expr)
(cases expr
[(Num n) n]
@@ -304,88 +304,3 @@ CFG for the BARF language:
;; evaluate an BARF program contained in a string
(define (run str)
(eval (parse str)))
; As we'ren't writing a lazy language, we need to use the Z combinator to delay evaluation of f (otherwise it'd never terminate). This factorial function also isn't tail recursive cause it's hard enough for me to understand already ;-;.
; Z = λf.(λx.(f λv.((x x) v)))(λx.(f λv.((x x) v)))
; factorial = (Y (λself.λn.if (<= n 1) 1 (* n (self (- n 1)))))
(test (run "
{with Z as {lambda f {
{lambda x {f of {lambda v {{x of x} of v}}}}
of
{lambda x {f of {lambda v {{x of x} of v}}}}
}}
{with factorial as {Z of
{lambda self {lambda n
{if {n is less than or equal to 1} then 1 else {* n {self of {- n 1}}}}
}
}}
{{{factorial of 4} is 24} and
{{factorial of 5} is 120}}}}") => #t)
(test (run "{{lambda f {f of 1}} of {lambda x {+ x 1}}}") => 2)
(test (run "{{lambda x {+ x 1}} of 2}") => 3)
(test (run "{{lambda + {+ + +}} of 2}") =error> "Can't create parameter binding to reserved name '+'.")
(test (run "{1 of 1}") =error> "eval-call: Expected lambda expression to call, instead got: (Num 1).")
(test (run "{with {x 2} {x of 1}}") =error> "eval-call: Expected lambda expression to call, instead got: (Num 2).")
(test (run "{and T T}") => #t)
(test (run "{and F aaaaaaaaaa}") => #f)
(test (run "{or T aaaaaaaaaa}") => #T)
(test (run "{or F T}") => #T)
(test (run "{or T T}") => #T)
(test (run "{not T}") => #F)
(test (run "{not F}") => #T)
(test (run "{with {p1 {< 1 2}} {with {p2 {< 3 4}} {and p1 p2}}}") => #T)
(test (run "{if T 1 2}") => 1)
(test (run "{if T then 1 else 2}") => 1)
(test (run "{with {T 2} {+ T 1}}") =error> "Can't create binding to reserved name 'T'.")
(test (run "{with {+ 2} {+ + 1}}") =error> "Can't create binding to reserved name '+'.")
(test (run "{< 1 2}") => #t)
(test (run "{< 2 2}") => #f)
(test (run "{< 2 1}") => #f)
(test (run "{1 is 2}") => #f)
(test (run "{= 1 2}") => #f)
(test (run "{= 2 2}") => #t)
(test (run "{2 is 2}") => #t)
(test (run "{<= 1 2}") => #t)
(test (run "{<= 2 2}") => #t)
(test (run "{<= 2 1}") => #f)
(test (run "{+}") => 0)
(test (run "{+ 12}") => 12)
(test (run "{+ 1 2 3}") => 6)
(test (run "{*}") => 1)
(test (run "{* 12}") => 12)
(test (run "{* 2 3 5}") => 30)
(test (run "{-}") =error> "parse-sexpr: bad syntax in (-)")
(test (run "{- 1}") => -1)
(test (run "{- 3 2 1}") => 0)
(test (run "{- 1 2 3}") => -4)
(test (run "{/}") =error> "parse-sexpr: bad syntax in (/)")
(test (run "{/ 2}") => 1/2)
(test (run "{/ 3 2 1}") => 3/2)
(test (run "{/ 1 2 3}") => 1/6)
(test (run "{+ x 1}") =error> "eval: free identifier: x")
;; tests (for simple expressions)
(test (run "5") => 5)
(test (run "{+ 5 5}") => 10)
(test (run "{with {x {+ 5 5}} {+ x x}}") => 20)
(test (run "{with {x 5} {+ x x}}") => 10)
(test (run "{with {x {+ 5 5}} {with {y {- x 3}} {+ y y}}}") => 14)
(test (run "{with {x 5} {with {y {- x 3}} {+ y y}}}") => 4)
(test (run "{with {x 5} {+ x {with {x 3} 10}}}") => 15)
(test (run "{with {x 5} {+ x {with {x 3} x}}}") => 8)
(test (run "{with {x 5} {+ x {with {y 3} x}}}") => 10)
(test (run "{with {x 5} {with {y x} y}}") => 5)
(test (run "{with {x 5} {with {x x} x}}") => 5)