view saveload.c @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents 76568becd6d6
children
line wrap: on
line source

#include "interp.h"
#include "structs.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
void save_program(char * filename)
{
	worker * aworkerlist;
	wire * awirelist;
	FILE * savefile;
	int def_num, version = 1;
	savefile = fopen(filename, "wb");
	if(!savefile)
		return;
	//deflist[current_def].num_workers = num_workers;
	//deflist[current_def].num_wires = num_wires;
	fwrite(&version, 4, 1, savefile);
	fwrite(&num_defs, 4, 1, savefile);
	fwrite(deflist, sizeof(worker_def), num_defs, savefile);
	for(def_num = 0; def_num < num_defs; ++def_num)
	{
		if(deflist[def_num].workerlist)
		{
			fwrite(&def_num, 4, 1, savefile);
			//fwrite(&(deflist[def_num].num_workers), 4, 1, savefile);
			fwrite(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, savefile);
			//fwrite(&(deflist[def_num].num_wires), 4, 1, savefile);
			fwrite(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, savefile);
		}
	}
	def_num = -1;
	fwrite(&def_num, 4, 1, savefile);
	fclose(savefile);
}*/

program * new_program(int def_storage, int comp_storage)
{
	defchunk * defs = malloc(sizeof(defchunk) + (def_storage - 1) * sizeof(worker_def));
	program * prog = malloc(sizeof(program));
	defs->num_defs = 0;
	defs->deflist[0].name = NULL;
	defs->defs_storage = def_storage;
	defs->next = NULL;
	prog->current = prog->defs = defs;
	//prog->deflist = malloc(sizeof(worker_def) * def_storage);
	//prog->num_defs = 0;
	//prog->defs_storage = def_storage;
	prog->companylist = malloc(sizeof(company) * comp_storage);
	prog->num_companies = 0;
	prog->companies_storage = comp_storage;
	prog->refcount = 1;
	VIS_InitializeCriticalSection(prog->lock);
	return prog;
}

int count_defs(defchunk * chunk)
{
	int total = 0;
	while(chunk)
	{
		total += chunk->num_defs;
		chunk = chunk->next;
	}
	return total;
}

void save_program(program * prog, char * filename)
{
	int version = 2;
	int total_bytes = 0;
	int zero = 0;
	int i;
	int num_defs;
	unsigned char size;
	custom_worker * aworker;
	//worker_def * deflist = prog->deflist;
	defchunk * defs = prog->defs;
	defchunk * current = defs;
	worker_def * deflist;
	FILE * savefile;
	savefile = fopen(filename, "wb");
	fwrite(&version, 4, 1, savefile);
	num_defs = count_defs(defs);
	fwrite(&(num_defs), 4, 1, savefile);
	while(current)
	{
		deflist = current->deflist;
		for(i = 0; i < current->num_defs; ++i)
		{
			size = strlen(deflist[i].name);
			fwrite(&size, 1, 1, savefile);
			fwrite(deflist[i].name, 1, size, savefile);
			total_bytes += (int)size + 1;
		}
		current = current->next;
	}
	if(total_bytes % 4 != 0)// pad to a 4 byte boundary
		fwrite(&zero, 1, 4-(total_bytes % 4), savefile);
	current = defs;
	while(current)
	{
		deflist = current->deflist;
		for(i = 0; i < current->num_defs; ++i)
		{
			if(deflist[i].type & USER_FLAG)
			{
				fwrite(&i, sizeof(int), 1, savefile);
				fwrite(&(deflist[i].num_inputs), sizeof(short), 1, savefile);
				fwrite(&(deflist[i].num_outputs), sizeof(short), 1, savefile);
				fwrite(&(deflist[i].type), sizeof(short), 1, savefile);
				fwrite(deflist[i].input_types, sizeof(short), deflist[i].num_inputs, savefile);
				fwrite(deflist[i].output_types, sizeof(short), deflist[i].num_outputs, savefile);
				total_bytes += sizeof(int) + (sizeof(short) * (3+deflist[i].num_inputs+deflist[i].num_outputs));
				if(total_bytes % 4 != 0)// pad to a 4 byte boundary
					fwrite(&zero, 1, 4-(total_bytes % 4), savefile);
				if((deflist[i].type & TYPE_MASK) == WORKER_TYPE)
				{
					aworker = deflist[i].implement_func;
					fwrite(&(aworker->num_workers), sizeof(int), 1, savefile);
					fwrite(aworker->workerlist, sizeof(worker), aworker->num_workers, savefile);
					fwrite(&(aworker->num_wires), sizeof(int), 1, savefile);
					fwrite(aworker->wirelist, sizeof(wire), aworker->num_wires, savefile);
				}
			}
		}
		current = current->next;
	}
	i = -1;
	fwrite(&i, sizeof(int), 1, savefile);
	fclose(savefile);
}

program * load_program(char * filename)
{
	custom_worker * aworker;
	int version;
	int i,j;
	int * def_lookup;
	char name[256];
	int total_bytes;
	int file_defs;
	unsigned char name_size;
	FILE * loadfile;
	char * code;
	int size;
	program * prog;
	loadfile = fopen(filename, "rb");
	if(!loadfile)
	{
		puts("Error: Could not open file");
		fflush(stdout);
		return NULL;
	}
	if(!strcmp(strrchr(filename,'.')+1, "vis"))
	{
		//TODO: Fixme
		/*fread(&version, 4, 1, loadfile);
		if(version != 2)
		{
			puts("Error: Can't read files of this version.");
			return NULL;
		}
		
		fread(&file_defs, 4, 1, loadfile);
		def_lookup = malloc(sizeof(int) * file_defs);
		total_bytes = 0;
		prog = new_program(file_defs, START_COMP_STORAGE);
		initworkers(prog);
		for(i = 0; i < file_defs; ++i)
		{
			fread(&name_size, 1, 1, loadfile);
			fread(name, 1, name_size, loadfile);
			name[name_size] = '\0';
			total_bytes += (int)name_size + 1;
			for(j = 0; j < prog->num_defs; ++j)
			{
				if(!strcmp(name, prog->deflist[j].name))
				{
					def_lookup[i] = j;
					break;
				}
			}
			if(j >= prog->num_defs) //couldn't find it in the list
			{
				def_lookup[i] = prog->num_defs;
				prog->deflist[prog->num_defs].name = malloc(name_size+1);
				strcpy(prog->deflist[prog->num_defs].name, name);
				++prog->num_defs;
			}
		}
		if(total_bytes % 4 != 0)// pad to a 4 byte boundary
			fread(&i, 1, 4-(total_bytes % 4), loadfile);
		do
		{
			fread(&i, sizeof(int), 1, loadfile);
			if(i >= 0)
			{
				i = def_lookup[i];
				fread(&(prog->deflist[i].num_inputs), sizeof(short), 1, loadfile);
				fread(&(prog->deflist[i].num_outputs), sizeof(short), 1, loadfile);
				fread(&(prog->deflist[i].type), sizeof(short), 1, loadfile);
				prog->deflist[i].input_types = malloc(sizeof(short) * (prog->deflist[i].num_inputs + prog->deflist[i].num_outputs));
				prog->deflist[i].output_types = prog->deflist[i].input_types + prog->deflist[i].num_inputs;
				fread(prog->deflist[i].input_types, sizeof(short), prog->deflist[i].num_inputs, loadfile);
				fread(prog->deflist[i].output_types, sizeof(short), prog->deflist[i].num_outputs, loadfile);
				total_bytes += sizeof(int) + (sizeof(short) * (3+prog->deflist[i].num_inputs+prog->deflist[i].num_outputs));
				if(total_bytes % 4 != 0)// pad to a 4 byte boundary
					fread(&j, 1, 4-(total_bytes % 4), loadfile);
				if((prog->deflist[i].type & TYPE_MASK) == WORKER_TYPE)
				{
					aworker = malloc(sizeof(custom_worker));
					prog->deflist[i].implement_func = aworker;
					fread(&(aworker->num_workers), sizeof(int), 1, loadfile);
					aworker->workerlist = malloc(sizeof(worker) * (aworker->num_workers + 512));
					fread(aworker->workerlist, sizeof(worker), aworker->num_workers, loadfile);
					fread(&(aworker->num_wires), sizeof(int), 1, loadfile);
					aworker->wirelist = malloc(sizeof(wire) * (aworker->num_wires + 1024));
					fread(aworker->wirelist, sizeof(wire), aworker->num_wires, loadfile);
					aworker->workers_to_wires_down = malloc(sizeof(int) * (aworker->num_wires + 1024));
					aworker->workers_to_wires_up = malloc(sizeof(int) * (aworker->num_wires + 1024));
					for(j = 0; j < aworker->num_workers; ++j)
						if(aworker->workerlist[j].type == 2)
							aworker->workerlist[j].value_index = def_lookup[aworker->workerlist[j].value_index];
				}
			}
		}while(i >= 0);*/
	}
	else
	{
		//Read text program
		fflush(stdout);
		fseek(loadfile, 0, SEEK_END);
		size = ftell(loadfile);
		fseek(loadfile, 0, SEEK_SET);
		fflush(stdout);
		code = malloc(size+1);
		fread(code, 1, size, loadfile);
		fclose(loadfile);
//		num_defs = 0;
		fflush(stdout);
		prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE);
		initpredefworkers(prog);
		fflush(stdout);	
		parse(code, size, prog);
		free(code);
		
//		num_workers = deflist[0].num_workers;
//		num_wires = deflist[0].num_wires;
	}
	return prog;
}

/*
void load_program(char * filename)
{
	worker * aworkerlist;
	wire * awirelist;
	FILE * loadfile;
	char * code;
	int size;
	int def_num, version;
	loadfile = fopen(filename, "rb");
	if(!loadfile)
	{
		puts("Error: Could not open file");
		return;
	}
	if(!strcmp(strrchr(filename,'.')+1, "vis"))
	{
		//Read binary program
		fread(&version, 4, 1, loadfile);
		if(version != 1)
		{
			puts("Error: Can't read files of this version.");
			return;
		}
		//program * new_program = malloc(sizeof(program));
	//	strcpy(program->filename, filename);
		fread(&num_defs, 4, 1, loadfile);
		//program->defs_storage = program->num_defs + 512;
		//new_program->deflist = malloc(sizeof(worker_def) * (program->defs_storaage));
		fread(deflist, sizeof(worker_def), num_defs, loadfile);
		fread(&def_num, 4, 1, loadfile);
		while(def_num >= 0 && !feof(loadfile))
		{
			deflist[def_num].workerlist = malloc((deflist[def_num].num_workers+512)*sizeof(worker));
			fread(deflist[def_num].workerlist, sizeof(worker), deflist[def_num].num_workers, loadfile);
			deflist[def_num].wirelist = malloc((deflist[def_num].num_wires+1024)*sizeof(wire));
			fread(deflist[def_num].wirelist, sizeof(wire), deflist[def_num].num_wires, loadfile);
			deflist[def_num].workers_to_wires_up = malloc((deflist[def_num].num_wires+1024)*sizeof(int));
			deflist[def_num].workers_to_wires_down = malloc((deflist[def_num].num_wires+1024)*sizeof(int));
			fread(&def_num, 4, 1, loadfile);
		}
		fclose(loadfile);
		num_workers = deflist[0].num_workers;
		num_wires = deflist[0].num_wires;
		initpredefworkers();
	}
	else
	{
		//Read text program
		fseek(loadfile, 0, SEEK_END);
		size = ftell(loadfile);
		fseek(loadfile, 0, SEEK_SET);
		code = malloc(size+1);
		fread(code, 1, size, loadfile);
		num_defs = 0;
		initpredefworkers();
		parse(code, size);
		num_workers = deflist[0].num_workers;
		num_wires = deflist[0].num_wires;
	}
}*/