1
0
Fork 0

Add non-interactive mode & Scheme Lisp tests

This commit is contained in:
Alex Kotov 2023-05-06 16:30:59 +04:00
parent 5863aab9f2
commit 6c84676c4a
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
6 changed files with 417 additions and 17 deletions

2
.gitignore vendored
View file

@ -2,3 +2,5 @@
/arcane-scheme-lisp
/arcane-scheme-lisp-test
/test.out

View file

@ -1,8 +1,16 @@
all: test
CAT = cat
CC = gcc
DIFF_Q = diff -q
RM_F = rm -f
CFLAGS = -Wall -Wextra
TEST_SCM = test.scm
TEST_EXP = test.txt
TEST_OUT = test.out
OBJS = \
src/builtins.c.o \
src/ctype.c.o \
@ -21,9 +29,11 @@ repl: arcane-scheme-lisp
test: arcane-scheme-lisp arcane-scheme-lisp-test
./arcane-scheme-lisp-test
$(CAT) $(TEST_SCM) | ./arcane-scheme-lisp > $(TEST_OUT)
$(DIFF_Q) $(TEST_EXP) $(TEST_OUT)
clean:
rm -f arcane-scheme-lisp arcane-scheme-lisp-test $(MAIN_OBJS) $(TEST_OBJS)
$(RM_F) arcane-scheme-lisp arcane-scheme-lisp-test $(MAIN_OBJS) $(TEST_OBJS) $(TEST_OUT)
arcane-scheme-lisp: $(MAIN_OBJS)
$(CC) -o $@ $^ $(CFLAGS)

View file

@ -4,6 +4,7 @@
#include "tokens.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -87,6 +88,7 @@ void token_add(const Lexer lexer)
void Lexer_lex(const Lexer self, const char chr)
{
assert(self);
assert(chr != EOF);
switch (self->state) {
case STATE_INIT:

View file

@ -10,32 +10,39 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
while (true) {
const bool is_tty = isatty(fileno(stdin));
do {
Tokens tokens = Tokens_new();
assert(tokens);
Lexer lexer = Lexer_new(tokens);
assert(lexer);
printf(">> ");
if (is_tty) printf(">> ");
while (true) {
const char chr = getchar();
if (chr == EOF) {
putchar('\n');
exit(EXIT_SUCCESS);
if (is_tty) {
if (chr == EOF) {
putchar('\n');
exit(EXIT_SUCCESS);
}
if (chr == '\n') break;
}
if (chr == '\n') {
Lexer_lex(lexer, '\n');
break;
}
if (chr == EOF) break;
Lexer_lex(lexer, chr);
}
Lexer_lex(lexer, '\n');
LEXER_DELETE(lexer);
if (Tokens_top(tokens) == NULL) continue;
@ -44,13 +51,15 @@ int main()
struct Object *const result = eval(program);
printf("=> ");
eval(Object_build_list(
2,
Object_new_symbol("displayln"),
Object_build_list(2, Object_new_symbol("quote"), result)
));
}
if (is_tty) {
printf("=> ");
eval(Object_build_list(
2,
Object_new_symbol("displayln"),
Object_build_list(2, Object_new_symbol("quote"), result)
));
}
} while (is_tty);
exit(EXIT_SUCCESS);
}

196
test.scm Normal file
View file

@ -0,0 +1,196 @@
(begin
(displayln "Hello, World!")
(newline)
(displayln "=== GROUP: Syntax ==============================================")
(newline)
(displayln "--- TEST: begin ------------------------------------------------")
(displayln (begin))
(displayln (begin 123))
(displayln (begin 123 456))
(displayln (begin 123 456 789))
(newline)
(displayln "--- TEST: if ---------------------------------------------------")
(displayln (if #true 123 456))
(displayln (if "foo" 123 456))
(displayln (if #false 123 456))
(newline)
(displayln "=== GROUP: Arcane Scheme Lisp internals ========================")
(newline)
(displayln "--- TEST: arcane/tokenize --------------------------------------")
(displayln (arcane/tokenize "("))
(displayln (arcane/tokenize "#false"))
'(displayln (arcane/tokenize "''"))
'(displayln (arcane/tokenize "'qwe'"))
(displayln (arcane/tokenize "(displayln (list 1))"))
(newline)
(displayln "--- TEST: arcane/typeof ----------------------------------------")
(displayln (arcane/typeof '()))
(displayln (arcane/typeof +))
(displayln (arcane/typeof (cons 123 456)))
(displayln (arcane/typeof #false))
'(displayln (arcane/typeof "#\n"))
(displayln (arcane/typeof 'foo))
(displayln (arcane/typeof "foo"))
(displayln (arcane/typeof 123))
(newline)
(displayln "=== GROUP: Basic data structures ===============================")
(newline)
(displayln "--- TEST: car --------------------------------------------------")
(displayln (car (cons 123 456)))
(newline)
(displayln "--- TEST: cdr --------------------------------------------------")
(displayln (cdr (cons 123 456)))
(newline)
(displayln "--- TEST: list -------------------------------------------------")
(displayln (list))
(displayln (list 123))
(displayln (list 123 456))
(newline)
(displayln "=== GROUP: Type predicates =====================================")
(newline)
(displayln "--- TEST: boolean? ---------------------------------------------")
(displayln (boolean? +))
(displayln (boolean? '()))
(displayln (boolean? #true))
(displayln (boolean? #false))
'(displayln (boolean? "#\n"))
(displayln (boolean? 'foo))
(displayln (boolean? "foo"))
(displayln (boolean? 123))
(displayln (boolean? (cons 123 456)))
(newline)
(displayln "--- TEST: char? ------------------------------------------------")
(displayln (char? +))
(displayln (char? '()))
(displayln (char? #true))
(displayln (char? #false))
'(displayln (char? "#\n"))
(displayln (char? 'foo))
(displayln (char? "foo"))
(displayln (char? 123))
(displayln (char? (cons 123 456)))
(newline)
(displayln "--- TEST: null? ------------------------------------------------")
(displayln (null? +))
(displayln (null? '()))
(displayln (null? #true))
(displayln (null? #false))
'(displayln (null? "#\n"))
(displayln (null? 'foo))
(displayln (null? "foo"))
(displayln (null? 123))
(displayln (null? (cons 123 456)))
(newline)
(displayln "--- TEST: number? ----------------------------------------------")
(displayln (number? +))
(displayln (number? '()))
(displayln (number? #true))
(displayln (number? #false))
'(displayln (number? "#\n"))
(displayln (number? 'foo))
(displayln (number? "foo"))
(displayln (number? 123))
(displayln (number? (cons 123 456)))
(newline)
(displayln "--- TEST: pair? ------------------------------------------------")
(displayln (pair? +))
(displayln (pair? '()))
(displayln (pair? #true))
(displayln (pair? #false))
'(displayln (pair? "#\n"))
(displayln (pair? 'foo))
(displayln (pair? "foo"))
(displayln (pair? 123))
(displayln (pair? (cons 123 456)))
(newline)
(displayln "--- TEST: procedure? -------------------------------------------")
(displayln (procedure? +))
(displayln (procedure? '()))
(displayln (procedure? #true))
(displayln (procedure? #false))
'(displayln (procedure? "#\n"))
(displayln (procedure? 'foo))
(displayln (procedure? "foo"))
(displayln (procedure? 123))
(displayln (procedure? (cons 123 456)))
(newline)
(displayln "--- TEST: string? ----------------------------------------------")
(displayln (string? +))
(displayln (string? '()))
(displayln (string? #true))
(displayln (string? #false))
'(displayln (string? "#\n"))
(displayln (string? 'foo))
(displayln (string? "foo"))
(displayln (string? 123))
(displayln (string? (cons 123 456)))
(newline)
(displayln "--- TEST: symbol? ----------------------------------------------")
(displayln (symbol? +))
(displayln (symbol? '()))
(displayln (symbol? #true))
(displayln (symbol? #false))
'(displayln (symbol? "#\n"))
(displayln (symbol? 'foo))
(displayln (symbol? "foo"))
(displayln (symbol? 123))
(displayln (symbol? (cons 123 456)))
(newline)
(displayln "=== GROUP: Type conversion =====================================")
(newline)
(displayln "--- TEST: number->string ---------------------------------------")
(displayln (number->string 123))
'(displayln (number->string "-123"))
(displayln (number->string 123456 16))
(newline)
(displayln "--- TEST: string->symbol ---------------------------------------")
(displayln (string->symbol ""))
(displayln (string->symbol " "))
(displayln (string->symbol "foo"))
(newline)
(displayln "--- TEST: symbol->string ---------------------------------------")
(displayln (symbol->string 'foo))
(newline)
(displayln "=== GROUP: Logical operators ===================================")
(newline)
(displayln "--- TEST: not --------------------------------------------------")
(displayln (not '()))
(displayln (not #true))
(displayln (not #false))
'(displayln (not "#\n"))
(displayln (not 'foo))
(displayln (not "foo"))
(displayln (not 123))
(displayln (not (cons 123 456)))
(newline)
(displayln "=== GROUP: Arithmetic operators ================================")
(newline)
(displayln "--- TEST: = ----------------------------------------------------")
(displayln(= 123))
(displayln(= 123 123))
(displayln(= 123 456))
(displayln(= 123 123 123))
(displayln(= 456 123 123))
(displayln(= 123 456 123))
(displayln(= 123 123 456))
(displayln(= 123 123 123 123))
(displayln(= 456 123 123 123))
(displayln(= 123 456 123 123))
(displayln(= 123 123 456 123))
(displayln(= 123 123 123 456))
(newline)
(displayln "--- TEST: + ----------------------------------------------------")
(displayln (+))
(displayln (+ 123))
(displayln (+ 1 10))
(displayln (+ 1 10 100))
(displayln (+ 1 10 100 1000))
(newline)
(displayln "--- TEST: - ----------------------------------------------------")
(displayln (- 0))
(displayln (- 123))
(displayln (- 100 1))
(displayln (- 100 1 2))
(displayln (- 100 1 2 3))
(displayln (- 100 1 2 3 4))
)

181
test.txt Normal file
View file

@ -0,0 +1,181 @@
"Hello, World!"
"=== GROUP: Syntax =============================================="
"--- TEST: begin ------------------------------------------------"
()
123
456
789
"--- TEST: if ---------------------------------------------------"
123
123
456
"=== GROUP: Arcane Scheme Lisp internals ========================"
"--- TEST: arcane/tokenize --------------------------------------"
((TOKEN_ROUND_OPEN . "("))
((TOKEN_TAG . "false"))
((TOKEN_ROUND_OPEN . "(") (TOKEN_IDENT . "displayln") (TOKEN_ROUND_OPEN . "(") (TOKEN_IDENT . "list") (TOKEN_NUM . "1") (TOKEN_ROUND_CLOSE . ")") (TOKEN_ROUND_CLOSE . ")"))
"--- TEST: arcane/typeof ----------------------------------------"
null
procedure
pair
boolean
symbol
string
number
"=== GROUP: Basic data structures ==============================="
"--- TEST: car --------------------------------------------------"
123
"--- TEST: cdr --------------------------------------------------"
456
"--- TEST: list -------------------------------------------------"
()
(123)
(123 456)
"=== GROUP: Type predicates ====================================="
"--- TEST: boolean? ---------------------------------------------"
#false
#false
#true
#true
#false
#false
#false
#false
"--- TEST: char? ------------------------------------------------"
#false
#false
#false
#false
#false
#false
#false
#false
"--- TEST: null? ------------------------------------------------"
#false
#true
#false
#false
#false
#false
#false
#false
"--- TEST: number? ----------------------------------------------"
#false
#false
#false
#false
#false
#false
#true
#false
"--- TEST: pair? ------------------------------------------------"
#false
#false
#false
#false
#false
#false
#false
#true
"--- TEST: procedure? -------------------------------------------"
#true
#false
#false
#false
#false
#false
#false
#false
"--- TEST: string? ----------------------------------------------"
#false
#false
#false
#false
#false
#true
#false
#false
"--- TEST: symbol? ----------------------------------------------"
#false
#false
#false
#false
#true
#false
#false
#false
"=== GROUP: Type conversion ====================================="
"--- TEST: number->string ---------------------------------------"
"123"
"1e240"
"--- TEST: string->symbol ---------------------------------------"
foo
"--- TEST: symbol->string ---------------------------------------"
"foo"
"=== GROUP: Logical operators ==================================="
"--- TEST: not --------------------------------------------------"
#false
#false
#true
#false
#false
#false
#false
"=== GROUP: Arithmetic operators ================================"
"--- TEST: = ----------------------------------------------------"
#true
#true
#false
#true
#false
#false
#false
#true
#false
#false
#false
#false
"--- TEST: + ----------------------------------------------------"
0
123
11
111
1111
"--- TEST: - ----------------------------------------------------"
0
123
99
97
94
90