forked from dhlorenz/CS236319
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
585 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"; |
Oops, something went wrong.