Added primitive unit testing.
This commit is contained in:
parent
85cc542d74
commit
8026138b9c
|
@ -152,13 +152,7 @@ struct cons_pointer allocate_cell( char* tag) {
|
||||||
if ( strncmp( &cell->tag.bytes[0], FREETAG, TAGLENGTH) == 0) {
|
if ( strncmp( &cell->tag.bytes[0], FREETAG, TAGLENGTH) == 0) {
|
||||||
freelist = cell->payload.free.cdr;
|
freelist = cell->payload.free.cdr;
|
||||||
|
|
||||||
fprintf( stderr, "Before: %c%c%c%c (%d)\n",
|
|
||||||
cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
|
|
||||||
cell->tag.bytes[3], cell->tag.value);
|
|
||||||
strncpy( &cell->tag.bytes[0], tag, 4);
|
strncpy( &cell->tag.bytes[0], tag, 4);
|
||||||
fprintf( stderr, "After: %c%c%c%c (%d)\n",
|
|
||||||
cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
|
|
||||||
cell->tag.bytes[3], cell->tag.value);
|
|
||||||
|
|
||||||
cell->count = 0;
|
cell->count = 0;
|
||||||
cell->payload.cons.car = NIL;
|
cell->payload.cons.car = NIL;
|
||||||
|
|
10
src/init.c
10
src/init.c
|
@ -18,17 +18,15 @@
|
||||||
#include "read.h"
|
#include "read.h"
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
printf( "Post scarcity software environment version %s\n", VERSION);
|
// printf( "Post scarcity software environment version %s\n", VERSION);
|
||||||
initialise_cons_pages();
|
initialise_cons_pages();
|
||||||
|
|
||||||
printf( "Ready\n>> ");
|
|
||||||
|
|
||||||
struct cons_pointer input = read( stdin);
|
struct cons_pointer input = read( stdin);
|
||||||
inc_ref( input);
|
//inc_ref( input);
|
||||||
printf( "\n:: ");
|
//printf( "\n:: ");
|
||||||
print( stdout, input);
|
print( stdout, input);
|
||||||
|
|
||||||
dump_pages(stdout);
|
// dump_pages(stdout);
|
||||||
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
|
@ -39,7 +39,11 @@ void print( FILE* output, struct cons_pointer pointer) {
|
||||||
for (struct cons_pointer p = pointer; stringp( p);
|
for (struct cons_pointer p = pointer; stringp( p);
|
||||||
p = pointer2cell( p).payload.string.cdr) {
|
p = pointer2cell( p).payload.string.cdr) {
|
||||||
// TODO: That's potentially a UTF character, needs more handling.
|
// TODO: That's potentially a UTF character, needs more handling.
|
||||||
fprintf( output, "%c", (char)pointer2cell( p).payload.string.character);
|
char c = (char)pointer2cell( p).payload.string.character;
|
||||||
|
|
||||||
|
if ( c != '\0') {
|
||||||
|
fprintf( output, "%c", c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fputc( '"', output);
|
fputc( '"', output);
|
||||||
} else if ( check_tag( pointer, TRUETAG)) {
|
} else if ( check_tag( pointer, TRUETAG)) {
|
||||||
|
|
149
src/read.c
149
src/read.c
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "consspaceobject.h"
|
#include "consspaceobject.h"
|
||||||
|
@ -21,67 +22,29 @@
|
||||||
lists
|
lists
|
||||||
Can't read atoms because I don't yet know what an atom is or how it's stored. */
|
Can't read atoms because I don't yet know what an atom is or how it's stored. */
|
||||||
|
|
||||||
/**
|
struct cons_pointer read_number( FILE* input, char initial);
|
||||||
* read a number from this input stream, given this initial character.
|
struct cons_pointer read_list( FILE* input, char initial);
|
||||||
*/
|
struct cons_pointer read_string( FILE* input, char initial);
|
||||||
struct cons_pointer read_number( FILE* input, char initial) {
|
|
||||||
int accumulator = 0;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
for (c = initial; isdigit( c); c = fgetc( input)) {
|
|
||||||
int digitvalue = (int)c - (int)'0';
|
|
||||||
accumulator = accumulator * 10 + digitvalue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* push back the character read which was not a digit */
|
|
||||||
fputc( c, input);
|
|
||||||
|
|
||||||
return make_integer( accumulator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct cons_pointer read_list( FILE* input) {
|
|
||||||
struct cons_pointer car = read( input);
|
|
||||||
struct cons_pointer cdr = NIL;
|
|
||||||
|
|
||||||
char c = fgetc( input);
|
|
||||||
|
|
||||||
if ( c != ')' ) {
|
|
||||||
cdr = read_list( input);
|
|
||||||
}
|
|
||||||
|
|
||||||
return make_cons( car, cdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct cons_pointer read_string( FILE* input) {
|
|
||||||
struct cons_pointer cdr = NIL;
|
|
||||||
struct cons_pointer result= NIL;
|
|
||||||
|
|
||||||
char c = fgetc( input);
|
|
||||||
|
|
||||||
if ( c != '"' ) {
|
|
||||||
result = make_string( c, read_string( input));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read the next object on this input stream and return a cons_pointer to it.
|
* Read the next object on this input stream and return a cons_pointer to it,
|
||||||
|
* treating this initial character as the first character of the object
|
||||||
|
* representation.
|
||||||
*/
|
*/
|
||||||
struct cons_pointer read( FILE* input) {
|
struct cons_pointer read_continuation( FILE* input, char initial) {
|
||||||
struct cons_pointer result = NIL;
|
struct cons_pointer result = NIL;
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
for (c = fgetc( input); isblank( c); c = fgetc( input));
|
for (c = initial; c == '\0' || isblank( c); c = fgetc( input));
|
||||||
|
|
||||||
switch( c) {
|
switch( c) {
|
||||||
case '(' : result = read_list(input);
|
case '(' :
|
||||||
|
case ')':
|
||||||
|
result = read_list(input, fgetc( input));
|
||||||
break;
|
break;
|
||||||
case '"': result = read_string(input);
|
case '"': result = read_string(input, fgetc( input));
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
case '1':
|
case '1':
|
||||||
|
@ -104,5 +67,91 @@ struct cons_pointer read( FILE* input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a number from this input stream, given this initial character.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read_number( FILE* input, char initial) {
|
||||||
|
int accumulator = 0;
|
||||||
|
int places_of_decimals = 0;
|
||||||
|
bool seen_period = false;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
fprintf( stderr, "read_number starting '%c' (%d)\n", initial, initial);
|
||||||
|
|
||||||
|
for (c = initial; isdigit( c); c = fgetc( input)) {
|
||||||
|
if ( c == '.') {
|
||||||
|
seen_period = true;
|
||||||
|
} else {
|
||||||
|
accumulator = accumulator * 10 + ((int)c - (int)'0');
|
||||||
|
|
||||||
|
if ( seen_period) {
|
||||||
|
places_of_decimals ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* push back the character read which was not a digit */
|
||||||
|
fputc( c, input);
|
||||||
|
|
||||||
|
return make_integer( accumulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a list from this input stream, which no longer contains the opening
|
||||||
|
* left parenthesis.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read_list( FILE* input, char initial) {
|
||||||
|
struct cons_pointer cdr = NIL;
|
||||||
|
struct cons_pointer result= NIL;
|
||||||
|
|
||||||
|
fprintf( stderr, "read_list starting '%c' (%d)\n", initial, initial);
|
||||||
|
|
||||||
|
if ( initial != ')' ) {
|
||||||
|
struct cons_pointer car = read_continuation( input, initial);
|
||||||
|
cdr = read_list( input, fgetc( input));
|
||||||
|
result = make_cons( car, cdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a string from this input stream, which no longer contains the opening
|
||||||
|
* double quote. Note that there is (for now) a problem with the list
|
||||||
|
* representation of a string, which is that there's no obvious representation of
|
||||||
|
* an empty string.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read_string( FILE* input, char initial) {
|
||||||
|
struct cons_pointer cdr = NIL;
|
||||||
|
struct cons_pointer result;
|
||||||
|
|
||||||
|
fprintf( stderr, "read_string starting '%c' (%d)\n", initial, initial);
|
||||||
|
|
||||||
|
switch ( initial) {
|
||||||
|
case '\0':
|
||||||
|
result = make_string( initial, NIL);
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
result = make_string( '\0', NIL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = make_string( initial, read_string( input, fgetc( input)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the next object on this input stream and return a cons_pointer to it.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read( FILE* input) {
|
||||||
|
return read_continuation( input, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
33
unit-tests.sh
Executable file
33
unit-tests.sh
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Early stage unit test runner for post-scarcity software environment.
|
||||||
|
# Uses bash to run every file in the unit-tests subdirectory; expects these
|
||||||
|
# to return 0 on success, anything else on fail.
|
||||||
|
|
||||||
|
# (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
# Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
|
||||||
|
tests=0
|
||||||
|
pass=0
|
||||||
|
fail=0
|
||||||
|
|
||||||
|
for file in unit-tests/*
|
||||||
|
do
|
||||||
|
echo ${file}
|
||||||
|
bash ${file}
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]
|
||||||
|
then
|
||||||
|
pass=$((${pass} + 1))
|
||||||
|
else
|
||||||
|
fail=$((${fail} + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
tests=$((${tests} + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Tested ${tests}, passed ${pass}, failed ${fail}"
|
||||||
|
|
||||||
|
exit ${fail}
|
||||||
|
|
13
unit-tests/empty-string.sh
Normal file
13
unit-tests/empty-string.sh
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected="\"\""
|
||||||
|
actual=`echo '""' | target/psse 2> /dev/null`
|
||||||
|
|
||||||
|
if [ "$expected" = "$actual" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Expected '$expected', got '$actual'"
|
||||||
|
exit 1
|
||||||
|
fi
|
13
unit-tests/fred.sh
Normal file
13
unit-tests/fred.sh
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected=\"Fred\"
|
||||||
|
actual=`echo '"Fred"' | target/psse 2> /dev/null`
|
||||||
|
|
||||||
|
if [ "$expected" = "$actual" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Expected '$expected', got '$actual'"
|
||||||
|
exit 1
|
||||||
|
fi
|
13
unit-tests/nil.sh
Normal file
13
unit-tests/nil.sh
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
expected=NIL
|
||||||
|
actual=`echo '()' | target/psse 2> /dev/null`
|
||||||
|
|
||||||
|
if [ "${expected}" = "${actual}" ]
|
||||||
|
then
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Expected '${expected}', got '${actual}'"
|
||||||
|
exit 1
|
||||||
|
fi
|
Loading…
Reference in a new issue