Skip to content

Commit

Permalink
Homework 4
Browse files Browse the repository at this point in the history
  • Loading branch information
vMaroon committed Jul 10, 2024
1 parent 639ae1c commit e35dea9
Show file tree
Hide file tree
Showing 6 changed files with 585 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Spr24/HW/Homework4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Homework 4

[Homework link](https://docs.google.com/document/d/1t2PkQlTUEOHOjd6E27zT8WvviIO6DxUTaWtXuAKQymw/edit?usp=sharing)

---

You can run the tests by running the following command in the terminal:

```
smlnj hw4_q[i]_tests.sml
```

You may notice that the first line in the test file is `use ...`, which means that your solution file must be accessible in the working directory. If you have your solution in a different directory, you can change the path in the test file.
7 changes: 7 additions & 0 deletions Spr24/HW/Homework4/hw4_q1.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
datatype Atom = SYMBOL of string | NIL;
datatype SExp = ATOM of Atom | CONS of (SExp * SExp);

exception Undefined;
exception Empty;

(* TODO *)
93 changes: 93 additions & 0 deletions Spr24/HW/Homework4/hw4_q1_tests.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use "hw4_q1.sml";

let
exception TestFailure of string;

local
fun sexp_to_string (ATOM(SYMBOL s)) = s
| sexp_to_string (ATOM NIL) = "NIL"
| sexp_to_string (CONS (x, y)) = "(" ^ sexp_to_string x ^ "." ^ sexp_to_string y ^ ")";
in
fun assert_equal (expected, actual, msg) =
if expected = actual then ()
else raise TestFailure (msg ^ ": expected " ^ sexp_to_string expected ^ ", but got " ^ sexp_to_string actual);
end;

fun run_tests tests =
let
fun runTest (name, test) =
(print ("Running " ^ name ^ "... ");
(test ();
print "Passed\n") handle
TestFailure msg => print ("Failed - " ^ msg ^ "\n"))
in
List.app runTest tests
end;

val env_tests = [
("Test initEnv",
fn () => let
val env = initEnv ()
val expected = ATOM NIL
val actual = (env "anySymbol") handle Undefined => ATOM NIL
in
assert_equal (expected, actual, "Test initEnv")
end),

("Test define",
fn () => let
val env = define "x" (initEnv ()) (ATOM (SYMBOL "value"))
val expected = ATOM (SYMBOL "value")
val actual = env "x"
in
assert_equal (expected, actual, "Test define")
end),

("Test pushEnv and topEnv",
fn () => let
val env1 = define "x" (initEnv ()) (ATOM (SYMBOL "value1"))
val env2 = define "x" (initEnv ()) (ATOM (SYMBOL "value2"))
val stack = pushEnv env1 (pushEnv env2 [])
val expected = ATOM (SYMBOL "value1")
val actual = (topEnv stack) "x"
in
assert_equal (expected, actual, "Test pushEnv and topEnv")
end),

("Test popEnv",
fn () => let
val env1 = define "x" (initEnv ()) (ATOM (SYMBOL "value1"))
val env2 = define "x" (initEnv ()) (ATOM (SYMBOL "value2"))
val stack = pushEnv env1 (pushEnv env2 [])
val poppedStack = popEnv stack
val expected = ATOM (SYMBOL "value2")
val actual = (topEnv poppedStack) "x"
in
assert_equal (expected, actual, "Test popEnv")
end),

("Test defineNested",
fn () => let
val env = define "x" (initEnv ()) (ATOM (SYMBOL "value1"))
val stack = pushEnv env []
val nestedStack = defineNested "y" stack (ATOM (SYMBOL "value2"))
val expected = ATOM (SYMBOL "value2")
val actual = find "y" nestedStack
in
assert_equal (expected, actual, "Test defineNested")
end),

("Test find",
fn () => let
val env1 = define "x" (initEnv ()) (ATOM (SYMBOL "value1"))
val env2 = define "x" (initEnv ()) (ATOM (SYMBOL "value2"))
val stack = pushEnv env1 (pushEnv env2 [])
val expected = ATOM (SYMBOL "value1")
val actual = find "x" stack
in
assert_equal (expected, actual, "Test find")
end)
];
in
run_tests env_tests
end;
49 changes: 49 additions & 0 deletions Spr24/HW/Homework4/hw4_q2.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use "hw4_q1.sml";

exception LispError;

(* Helper function - feel free to delete *)
fun first (x, _) = x;

local
fun tokenize x =
String.tokens (fn c: char => c = #" ")
(String.translate (fn #"(" => "( " | #")" => " )" | c => str c) x);

(* ======================= *)
(* INSERT YOUR PARSER HERE *)
(* ======================= *)

(* Helper functions - feel free to delete *)
(* ====================================== *)
fun is_digit c = c >= #"0" andalso c <= #"9";

fun is_number str =
let
fun check [] = true
| check (c::cs) = is_digit c andalso check cs

val chars = String.explode str
in
if List.null chars then false else check chars
end;

fun char_to_int c = ord(c) - ord(#"0")

fun string_to_int str =
let
fun convert [] acc = acc
| convert (c::cs) acc = convert cs (10 * acc + char_to_int c)
in
convert (String.explode str) 0
end;

fun sexp_to_int sexp =
case sexp of
ATOM (SYMBOL s) => string_to_int s
| _ => raise LispError;
(* ====================================== *)

in
fun eval string_exp env = (* TODO, should have `parse (tokenize string_exp)` somewhere *)
end;
191 changes: 191 additions & 0 deletions Spr24/HW/Homework4/hw4_q2_tests.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
use "hw4_q2.sml";

(*
//////////////////////////////////////////////////////
////////////////////// TESTS /////////////////////////
//////////////////////////////////////////////////////
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⣘⣩⣅⣤⣤⣄⣠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⢈⣻⣿⣿⢷⣾⣭⣯⣯⡳⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣧⠻⠿⡻⢿⠿⡾⣽⣿⣳⣧⡷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢰⡶⢈⠐⡀⠀⠀⠁⠀⠀⠀⠈⢿⡽⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢫⢅⢠⣥⣐⡀⠀⠀⠀⠀⠀⠀⢸⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀keep⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠆⠡⠱⠒⠖⣙⠂⠈⠵⣖⡂⠄⢸⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀it⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠆⠀⠰⡈⢆⣑⠂⠀⠀⠀⠀⠀⠏⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀rolling⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢗⠀⠱⡈⢆⠙⠉⠃⠀⠀⠀⠀⠃⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠦⡡⢘⠩⠯⠒⠀⠀⠀⢀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⢔⡢⢡⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⢆⠸⡁⠋⠃⠁⠀⢀⢠⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡰⠌⣒⠡⠄⠀⢀⠔⠁⣸⣿⣷⣤⣀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣐⣤⡄⠀⠀⠘⢚⣒⢂⠇⣜⠒⠉⠀⢀⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣦⣔⣀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⡀⢀⢠⣤⣶⣿⣿⣿⡆⠀⠀⠐⡂⠌⠐⠝⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢨⣶⣿⣿⣿⣿⣿⣿⣿⣿⣤⡶⢐⡑⣊⠀⡴⢤⣀⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠷⡈⠀⠶⢶⣰⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣉⠑⠚⣙⡒⠒⠲⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡁⠀⠀⠀⠀⠀⠀⠀⠀
⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡷⠶⠀⠀⠤⣬⣍⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀
⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣛⣙⠀⢠⠲⠖⠶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣭⣰⢘⣙⣛⣲⣿⣿⣿⣿⡿⡻⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠀⠀
⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠶⢾⡠⢤⣭⣽⣿⣿⣿⣿⡟⣱⠦⠄⠤⠐⡄⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⡀⠀
⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡛⣻⡕⠶⠶⣿⣿⣿⣿⣿⣿⣗⣎⠒⣀⠃⡐⢀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀
⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣭⣹⣏⣛⣛⣿⣿⣿⣿⣿⣿⣿⣞⣍⣉⢉⠰⠀⠠⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠅
⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠶⢼⡧⢤⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣣⣡⣛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣅
⡿⣷⣽⡿⠛⠋⠉⣉⡐⠶⣾⣾⣟⣻⡕⠶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣹⣫⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠗
⢸⣿⣟⣥⡶⢘⡻⢶⡹⣛⣼⣿⣯⣽⢯⣙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⣿⣿⣿⣿⣿⣿⡿⠿⠟⠁⠀
⠘⢟⣾⣿⣿⣚⠷⣳⢳⣫⣽⣿⣛⣾⡷⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠀⠁⠀⠈⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠙⢋⣿⣿⣯⣙⣯⣵⣿⣿⣯⣽⣟⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠉⠛⢻⠟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣟⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣡⣿⣿⣿⣿⡗⣮⢻⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣧⣮⢻⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*)

Control.Print.printLength := 100;
Control.Print.printDepth := 100;

fun print_atom (SYMBOL s) = s
| print_atom NIL = "nil"

fun sexp_to_string (ATOM a) = print_atom a
| sexp_to_string (CONS (car, cdr)) = "(" ^ print_cons (car, cdr) ^ ")"

and print_cons (car, ATOM NIL) = sexp_to_string car
| print_cons (car, CONS (cadr, cddr)) = sexp_to_string car ^ " " ^ print_cons (cadr, cddr)
| print_cons (car, cdr) = sexp_to_string car ^ " . " ^ sexp_to_string cdr;

val env: (string -> SExp) list = emptyNestedEnv();

(* Test the evaluation of basic atoms *)
val test_simple1 = sexp_to_string (first (eval "()" env)) = "nil";
val test_simple2 = sexp_to_string (first (eval "t" env)) = "t";

(* Test the evaluation of unknown atoms *)
val test_simple3 = sexp_to_string (first (eval "(unknown)" env)) = "lisp-error";

(* Test the evaluation of the cons function *)
val test_simple4 = sexp_to_string (first (eval "(cons 2 3)" env)) = "(2 . 3)";

(* Test the evaluation of nested cons functions *)
val test_simple5 = sexp_to_string (first (eval "(cons (cons 2 3) (cons 4 5))" env)) = "((2 . 3) 4 . 5)";

(* Test the evaluation of the car function *)
val test_simple6 = sexp_to_string (first (eval "(car (cons 2 3))" env)) = "2";

(* Test the evaluation of the cdr function *)
val test_simple7 = sexp_to_string (first (eval "(cdr (cons 2 3))" env)) = "3";

(* Test the evaluation of the eq function *)
val test_simple8 = sexp_to_string (first (eval "(eq 2 2)" env)) = "t";
val test_simple9 = sexp_to_string (first (eval "(eq 2 3)" env)) = "nil";

(* Test the evaluation of the atom function *)
val test_simple10 = sexp_to_string (first (eval "(atom (cons 2 3))" env)) = "nil";
val test_simple11 = sexp_to_string (first (eval "(atom 2)" env)) = "t";

(* Test the evaluation of the cond function *)
val test_simple12 = sexp_to_string (first (eval "(cond ((eq 2 2) 3) ((eq 2 3) 4))" env)) = "3";
val test_simple13 = sexp_to_string (first (eval "(cond ((eq 2 3) 3) ((eq 3 4) 3) ((quote am-i-nil?) 4))" env)) = "4";
val test_simple14 = sexp_to_string (first (eval "(cond ((eq 2 2) 5))" env)) = "5";

(* Test the evaluation of the quote function *)
val test_simple15 = sexp_to_string (first (eval "(quote 2)" env)) = "2";
val test_simple16 = sexp_to_string (first (eval "(quote (2 3))" env)) = "(2 3)";

val test_simple17 = sexp_to_string (first (eval "(quote (1 2 3))" env)) = "(1 2 3)";

(* Test the evaluation of the lambda function *)
val test_simple18 = sexp_to_string (first (eval "((lambda (x) x) 2)" env)) = "2";
val test_simple19 = sexp_to_string (first (eval "((lambda (x y) (cons x y)) 2 3)" env)) = "(2 . 3)";
val test_simple20 = sexp_to_string (first (eval "((lambda (x y) (cons x y)) 2 (quote 3))" env)) = "(2 . 3)";
val test_simple21 = sexp_to_string (first (eval "((lambda (x y) (+ x y)) 2 3)" env)) = "5";
val test_simple22 = sexp_to_string (first (eval "((lambda (x y) (+ x y)) 2 3 4)" env)) = "lisp-error";

(* Test the evaluation of null *)
val test_simple23 = sexp_to_string (first (eval "(null (quote 2))" env)) = "nil";
val test_simple24 = sexp_to_string (first (eval "(null (quote ()))" env)) = "t";

(* Test the evaluation of the label function *)
(* Test the evaluation of the math operations *)
(* cons on quotes *)
val test_advanced1 = sexp_to_string (first (eval "(cons (quote 1) (quote 2))" env)) = "(1 . 2)";
val test_advanced2 = sexp_to_string (first (eval "(cons (quote 3) (cons (quote 1) (quote 2)))" env)) = "(3 1 . 2)";

(* car on cdr *)
val test_advanced3 = sexp_to_string (first (eval "(car (cdr (quote (1 2 3))))" env)) = "2";
val test_advanced4 = sexp_to_string (first (eval "(car (cdr (cdr (quote (1 2 3)))))" env)) = "3";
val test_advanced5 = sexp_to_string (first (eval "(car (cdr (cdr (cdr (quote (1 2 3))))))" env)) = "lisp-error";

(* cdr on car *)
val test_advanced6 = sexp_to_string (first (eval "(cdr (car (quote ((1 2) 3))))" env)) = "(2)";
val test_advanced7 = sexp_to_string (first (eval "(cdr (car (cdr (quote ((1 2) 3)))))" env)) = "lisp-error";

(* eq on cons *)
val test_advanced8 = sexp_to_string (first (eval "(eq (cons 1 2) (cons 1 2))" env)) = "nil";

(* math ops *)
val test_advanced9 = sexp_to_string (first (eval "(+ 1 2)" env)) = "3";
val test_advanced10 = sexp_to_string (first (eval "(- 1 2)" env)) = "~1";
val test_advanced11 = sexp_to_string (first (eval "(* 2 3)" env)) = "6";
val test_advanced12 = sexp_to_string (first (eval "(/ 6 2)" env)) = "3";
val test_advanced13 = sexp_to_string (first (eval "(mod 5 2)" env)) = "1";

(* comparison ops *)
val test_advanced14 = sexp_to_string (first (eval "(= 1 1)" env)) = "t";
val test_advanced15 = sexp_to_string (first (eval "(= 1 2)" env)) = "nil";
val test_advanced16 = sexp_to_string (first (eval "(/= 1 2)" env)) = "t";
val test_advanced17 = sexp_to_string (first (eval "(/= 1 1)" env)) = "nil";
val test_advanced18 = sexp_to_string (first (eval "(< 1 2)" env)) = "t";
val test_advanced19 = sexp_to_string (first (eval "(< 2 1)" env)) = "nil";
val test_advanced20 = sexp_to_string (first (eval "(> 2 1)" env)) = "t";
val test_advanced21 = sexp_to_string (first (eval "(> 1 2)" env)) = "nil";

(* nested lambda *)
val test_advanced22 = sexp_to_string (first (eval "((lambda (x) ((lambda (y) (cons x y)) (quote b))) (quote a))" env)) = "(a . b)";
val test_advanced23 = sexp_to_string (first (eval "((lambda (x) \
\((lambda (y) \
\(+ x y)) \
\3)) \
\2)" env)) = "5";

(* nested lambda with cond *)
val test_advanced24 = sexp_to_string (first (eval "((lambda (x) \
\(cond \
\((eq x 1) 1) \
\((eq x 2) 2) \
\(t 3))) \
\2)" env)) = "2";

val test_advanced25 = sexp_to_string (first (eval "((lambda (x) \
\((lambda (y) \
\(cond \
\((eq y 1) 1) \
\((eq y 2) 2) \
\(t 3))) \
\x)) \
\2)" env)) = "2";

(* make sure lambda doesnt affect bindings *)
local
val (_, env_with_x) = eval "((lambda (x) \
\(cond \
\((eq x 1) 1) \
\((eq x 2) 2) \
\(t 3))) \
\2)" env;
in
val lambda_local = sexp_to_string ((find "x" env_with_x) handle
Undefined => (ATOM (SYMBOL "good"))
| _ => (ATOM (SYMBOL "bad"))) = "good"
end;

(* nested lambda with label *)
val test_advanced26 = sexp_to_string (first (eval "((label fact \
\(lambda (n) \
\(cond ((eq n 0) 1) \
\(t (* n (fact (- n 1))))))) \
\5)" env)) = "120";

(* freestyle of combinations on atom, null, eq, car, cdr, cons *)
val freestyle1 = sexp_to_string (first (eval "(atom (quote (1 2 3)))" env)) = "nil";
val freestyle2 = sexp_to_string (first (eval "(null (quote ()))" env)) = "t";
val freestyle3 = sexp_to_string (first (eval "(eq (car (quote (1 2 3))) 1)" env)) = "t";
val freestyle4 = sexp_to_string (first (eval "(eq (cdr (quote (1 2 3))) (quote (2 3)))" env)) = "nil";
Loading

0 comments on commit e35dea9

Please sign in to comment.