implementation module memory;

import StdDynamicTypes;
import code from "mem.obj";
import StdEnv;

:: *Mem = Mem;

getMemory :: !*World -> (!*Mem,!*World);
getMemory world
	= (Mem,world);
	
putMemory :: !*Mem !*World -> !*World;
putMemory mem world
	= world;

readWord :: !Int !*Mem -> (!Int,!*Mem);
readWord address mem
	= code {
		jmp read_word
	};

readHalfWord :: !Int !*Mem -> (!Int,!*Mem);
readHalfWord address mem
	= code {
		jmp read_half_word
	};
	
readByte:: !Int !*Mem -> (!Int,!*Mem);
readByte address mem
	= code {
		jmp read_byte
	};
	
readWord1 :: !Int !*a -> (!Int,!*a);
readWord1 address mem
	= code {
		jmp read_word
	};
	
readHalfWord1 :: !Int !*a -> (!Int,!*a);
readHalfWord1 address mem
	= code {
		jmp read_half_word
	};
	
readByte1 :: !Int !*a -> (!Int,!*a);
readByte1 address mem
	= code {
		jmp read_byte
	};
	
address_of_buffer :: !*a -> (!Int,!*a);
address_of_buffer mem
	= code {
		jmp address_of_buffer
	};
	
writeWord1 :: !Int !Int !*a -> !*a;
writeWord1 value ptr _
	= code {
		jmp write_word
	};
	
writeByte1 :: !Char !Int !*a -> !*a;
writeByte1 value ptr _
	= code {
		jmp write_byte
	};


// (defining module_name,data address)
get_module_id :: !DummyModuleID -> (!String,!Int);
get_module_id module_id
	# address
		= get_module_id1 module_id;
	# (length,mem)
		= readWord address Mem;
	# module_name
		= createArray length ' ';
	# (module_name,mem)
		= collect 0 length (address + 4) module_name mem;
	= (module_name,address);
where {
	get_module_id1 :: !DummyModuleID -> !Int;
	get_module_id1 _
		= code {
			jmp		get_module_id
		};
		
	collect i limit address module_name mem
		| i == limit
			= (module_name,mem);
			
			# (byte,mem)
				= readByte address mem;
			= collect (inc i) limit (inc address) {module_name & [i] = toChar byte} mem;
}