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) {
|
||||
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);
|
||||
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->payload.cons.car = NIL;
|
||||
|
|
10
src/init.c
10
src/init.c
|
@ -18,17 +18,15 @@
|
|||
#include "read.h"
|
||||
|
||||
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();
|
||||
|
||||
printf( "Ready\n>> ");
|
||||
|
||||
struct cons_pointer input = read( stdin);
|
||||
inc_ref( input);
|
||||
printf( "\n:: ");
|
||||
//inc_ref( input);
|
||||
//printf( "\n:: ");
|
||||
print( stdout, input);
|
||||
|
||||
dump_pages(stdout);
|
||||
// dump_pages(stdout);
|
||||
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
||||
|
||||
return(0);
|
||||
|
|
|
@ -39,7 +39,11 @@ void print( FILE* output, struct cons_pointer pointer) {
|
|||
for (struct cons_pointer p = pointer; stringp( p);
|
||||
p = pointer2cell( p).payload.string.cdr) {
|
||||
// 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);
|
||||
} else if ( check_tag( pointer, TRUETAG)) {
|
||||
|
|
149
src/read.c
149
src/read.c
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "consspaceobject.h"
|
||||
|
@ -21,67 +22,29 @@
|
|||
lists
|
||||
Can't read atoms because I don't yet know what an atom is or how it's stored. */
|
||||
|
||||
/**
|
||||
* read a number from this input stream, given this initial character.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
struct cons_pointer read_number( FILE* input, char initial);
|
||||
struct cons_pointer read_list( FILE* input, char initial);
|
||||
struct cons_pointer read_string( FILE* input, char initial);
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
char c;
|
||||
|
||||
for (c = fgetc( input); isblank( c); c = fgetc( input));
|
||||
for (c = initial; c == '\0' || isblank( c); c = fgetc( input));
|
||||
|
||||
switch( c) {
|
||||
case '(' : result = read_list(input);
|
||||
case '(' :
|
||||
case ')':
|
||||
result = read_list(input, fgetc( input));
|
||||
break;
|
||||
case '"': result = read_string(input);
|
||||
case '"': result = read_string(input, fgetc( input));
|
||||
break;
|
||||
case '0':
|
||||
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