datadec.c 2.72 KB
Newer Older
dcw's avatar
dcw committed
1 2 3 4 5 6 7 8 9 10
/*
 *                      DATA DECLARATION BUILDER
 *                      ==== =========== =======
 *
 ******* Author:
 *
 *      Duncan White, Imperial College, London, England.
 *
 ******* Description:
 *
11
 *      This program builds C data declarations,
dcw's avatar
dcw committed
12
 *	constructor and deconstructor functions and write functions
13 14
 *	from a series of Haskell/Miranda/Hope style recursive data declarations.
 *	(with optional hints on printing, and optionally, free_* functions)
dcw's avatar
dcw committed
15
 *
dcw's avatar
dcw committed
16
 *      The output produced is placed in pair of files (eg. x.c and x.h )
17 18 19 20
 *	which together form a module provided the relevant data types.
 *	NEW in 2018: in addition, we write a useful summary of types,
 *	shapes and the types of the shape parameters into a .x.dd file,
 *	this can be used by experimental client-side tools such as "CPM.perl".
dcw's avatar
dcw committed
21 22
 */

23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <stdbool.h>
26
#include <string.h>
27

dcw's avatar
dcw committed
28 29 30
#include "struct.h"
#include "lexer.h"
#include "parser.h"
dcw's avatar
dcw committed
31
#include "decs.h"
32
#include "optimize.h"
dcw's avatar
dcw committed
33 34


35
#define MUSTBE(b)	{if(!(b)){fprintf(stderr,"Usage: datadec [-vnof] outfile [infile]\n");exit(1);}}
dcw's avatar
dcw committed
36 37 38 39 40 41

#define NEED_ANOTHER_ARG	MUSTBE( IS_ANOTHER_ARG )
#define REQUIRE_NO_MORE_ARGS	MUSTBE( argc == arg )
#define IS_ANOTHER_ARG		(argc > arg)


42 43
#define CHUNKSIZE 10000

dcw's avatar
dcw committed
44 45
typedef char bigstr[ CHUNKSIZE ];

46

dcw's avatar
dcw committed
47
int main( int argc, char **argv )
dcw's avatar
dcw committed
48
{
dcw's avatar
dcw committed
49 50
	char		*basename;
	char		*s;
dcw's avatar
dcw committed
51 52
        declnlist	declns;
	int		len;
dcw's avatar
dcw committed
53
	int		arg;
dcw's avatar
dcw committed
54
	bigstr		exports, globals, begin;
dcw's avatar
dcw committed
55

dcw's avatar
dcw committed
56 57 58
	arg = 1;
	NEED_ANOTHER_ARG;

59
	verbose = false; opt = true;
dcw's avatar
dcw committed
60
	while( *(s=argv[arg]) == '-' )
dcw's avatar
dcw committed
61
	{
dcw's avatar
dcw committed
62 63 64 65 66
		for( s++; *s; s++ )
		{
			switch( *s )
			{
			case 'v':
67
				verbose = true;
dcw's avatar
dcw committed
68
				break;
69
			case 'f':
70
				makefree = true;
71
				break;
dcw's avatar
dcw committed
72
			case 'n':
73
				opt = false;
dcw's avatar
dcw committed
74
				break;
75
			case 'o':
76
				opt = true;
77
				break;
dcw's avatar
dcw committed
78
			default:
79 80 81
				fprintf( stderr,
					"datadec: illegal option -%c\n", *s );
				exit(1);
dcw's avatar
dcw committed
82 83
			}
		}
dcw's avatar
dcw committed
84
		arg++;
dcw's avatar
dcw committed
85
		NEED_ANOTHER_ARG;
dcw's avatar
dcw committed
86
	}
dcw's avatar
dcw committed
87

dcw's avatar
dcw committed
88
	basename = argv[arg++];
dcw's avatar
dcw committed
89
	len = strlen( basename );
dcw's avatar
dcw committed
90 91
	if( !strcmp( basename+len-2, ".c" ) )
	{
dcw's avatar
dcw committed
92 93 94
		basename[len-2] = '\0';
	}

dcw's avatar
dcw committed
95 96
        if( IS_ANOTHER_ARG ) {
                lexfile = fopen( argv[arg], "r" );
97 98 99 100 101 102
                if( lexfile == NULL )
		{
			fprintf( stderr, "datadec: can't open '%s'\n",
				argv[arg] );
			exit(1);
		}
dcw's avatar
dcw committed
103
		arg++;
dcw's avatar
dcw committed
104 105 106
        } else {
                lexfile = stdin;
        }
dcw's avatar
dcw committed
107 108 109

	REQUIRE_NO_MORE_ARGS;

110
        if( ! parse_data( exports, globals, begin, &declns ) )
dcw's avatar
dcw committed
111 112
	{
		fprintf( stderr, "datadec: can't parse input properly\n" );
113 114 115 116 117 118 119 120 121
		exit(1);
	}
	if( verbose )
	{
		printf( "datadec: declns are:\n\n" );
		print_declnlist( declns );
		printf( "exports = {%s}\n", exports );
		printf( "globals = {%s}\n", globals );
		printf( "begin = {%s}\n", begin );
dcw's avatar
dcw committed
122
	}
123 124
	optimize( declns );
	make_declns( exports, globals, begin, declns, basename );
dcw's avatar
dcw committed
125
	exit(0);
126
	/*NOTREACHED*/
dcw's avatar
dcw committed
127
}