	# I/O *core* functions
	# All of this is likely to change once Parrot gets
	#    the I/O sorted out.
	#
	# Not a lot of error handling here yet
.sub _READCHARS 	# string readchars(int numchar, int fd)
	saveall
	.param int numchar
	.param int fd
	ne fd, 0, NORESET
	call _line_read
NORESET:find_global $P0, "FDS"
	$P1=$P0[fd]
	set $S0, ""
	read $S0, $P1, numchar
	.return $S0
	restoreall
	ret
.end
.sub _OPEN		# void open(string filename, string mode, int fd)
	saveall
	.param string filename
	.param string mode
	.param int fd
	.local int error
	open $P1, filename, mode
	err error
	eq error, 0, OPEN_OK
	print "Error "
	print error
	print " in open\n"
	end
OPEN_OK:
	find_global $P0, "FDS"
	$P0[fd]=$P1
	store_global "FDS", $P0
	restoreall
	ret
.end
.sub _CLOSE		# void close(int fd)
	saveall
	.param int fd
	.local int error
	find_global $P0, "FDS"
	set $P1, $P0[fd]
	close $P1
	err error
	eq error, 0, CLOSE_OK
	print "Error "
	print error
	print " in close\n"
	end
CLOSE_OK:
	store_global "FDS", $P0
	restoreall
	ret
.end
.sub _WRITE		# void writestring(int fd, 1, string stuff)
	saveall
	.param int fd
	.local string buffer
	.local int oldprintcol

	find_global $P1, "PRINTCOL"
	oldprintcol=$P1["value"]
	call _BUILTIN_DISPLAY_WORK
	.result buffer
	find_global $P1, "PRINTCOL"
	$P1["value"]=oldprintcol
	store_global "PRINTCOL", $P1

	find_global $P0, "FDS"
	set $P1, $P0[fd]
	print $P1, buffer
	restoreall
	ret
.end

#
#        # ###########################
#        # READLINE    Read FD until EOL
#        # Takes:
#        #       I1   FD to read
#        #       S0   String read (EOL included!)
#        #
#        # Returns:
#        #       I0   Error?
.sub _READLINE		# string readline(int fd)
	saveall
	.param int fd
	find_global $P0, "FDS"
	$P1=$P0[fd]
	set $S0, ""
	readline $S0, $P1
	.return $S0
	restoreall
	ret
.end
#	# ###########################
#	# SPLITLINE	Splits a line into parts
#	# Outputs:
#	# 	P1	Array of strings
.sub _SPLITLINE		# PerlArray splitline (string line, int splitflag)
	saveall
	.param string line
	.param int splitflag
	.local string token
	.arg line
	call _CHOMP
	.result line

	$P1=new PerlArray
	eq splitflag, 0, SPLITSINGLE

SPLITAGAIN:
	length $I0, line
	eq $I0, 0, SPLITEND
	.arg line
	call _REMOVETOK
	.result line
	.result token
	push $P1, token
	branch SPLITAGAIN

SPLITEND:
	set $I1, $P1
	ne $I1, 0, SPLITGONE
	push $P1, ""
	branch SPLITGONE

SPLITSINGLE:
	push $P1, line

SPLITGONE:
	.return $P1
	restoreall

	ret
.end
#
#	# ############################
#	# Remove a token from the front of S0
#	# BASIC's Rules:
#	#    COMMAS separate tokens
#	#    Leading/trailing spaces ignored and removed.
#	#    Quotes can surround part of a token w/commas and spaces
.sub _REMOVETOK		# (string token, string neworiginal) removetok(string original)
	saveall
	.param string original
	set $I1, 0	# Inquote
	set $S1, ""	# Base string
TOKLOOP:
	length $I0, original
	eq $I0, 0, EOTOK
	substr $S2, original, 0, 1
	dec $I0
	substr original, original, 1, $I0
	eq $S2, '"', QUOTE
	eq $I1, 1, QUOTED
	eq $S2, " ", WHITESP
	eq $S2, "\r", WHITESP
	eq $S2, "\n", WHITESP
	eq $S2, ",", EOTOK
	concat $S1, $S1, $S2
	branch TOKLOOP
WHITESP:length $I0, $S1
	eq $I0, 0, TOKLOOP  # Leading spaces
QUOTED: concat $S1, $S1, $S2
	branch TOKLOOP
QUOTE:	eq $I1, 0, STARTQ
	set $I1, 0
	branch TOKLOOP
STARTQ: set $I1, 1
	branch TOKLOOP
EOTOK:	.return $S1	# The token
	.return original# The original, w/o the token
	restoreall
.end

#        # ###########################
#        # CHOMP      Remove trailing \r\n thingies from S0
.sub _CHOMP	# string chomp(string line)
	saveall
	.param string line
	length $I0, line
	dec $I0
	le $I0, 0, CHOMPOK
CHOMPLOOK:
	substr $S1, line, $I0, 1
	eq $S1, "\n", CHOMPIT
	eq $S1, "\r", CHOMPIT
	eq $S1, "", CHOMPIT
	branch CHOMPOK
CHOMPIT:substr line, line, 0, $I0
	dec $I0
	le $I0, 0, CHOMPOK
	branch CHOMPLOOK
CHOMPOK:.return line
	restoreall
	ret
.end

#
#ERR_INPFIELDS:
#	print "Input field count wrong"
#	branch GEN_ERROR
#ERR_BADF:
#	print "File descriptor is incorrect"
#	branch GEN_ERROR
