373 lines · 7.3 KB · Brainfuck
RawDownload
##       Software from the book "Inferno Programming with Limbo"#       published by John Wiley & Sons, January 2003.##       p. Stanley-Marbell <pip@gemusehaken.org>#implement Pled; include "sys.m";include "draw.m";include "bufio.m";include "pled.m"; sys			: Sys;bufio			: Bufio;FD			: import sys;Iobuf 			: import bufio; cctlfd			: ref Sys->FD;curlineidx, cursoridx	: int = 0;numlines, mode		: int = 0;stdin, stdout		: ref Sys->FD;  init (nil : ref Draw->Context, argv : list of string){        sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;         stdin = sys->fildes(0);        stdout = sys->fildes(1);         param := tl argv;        while (param != nil)        {                (n, err) := pedit(hd param);                if (n != 0)                {			sys->print("\nPled :: %s\n\n", err);                }                param = tl param;        } 	cctlfd = sys->open("/dev/consctl", sys->OWRITE);	sys->seek(cctlfd, 0, sys->SEEKSTART);	sys->write(cctlfd, array of byte "rawoff", len "rawoff");} pedit (filename : string) : (int, string){	buf			:= array[1] of byte;	consfd 			: ref FD;	key			: int = 0;	lines			: array of Line; 	tmpstr			: string; 	cctlfd = sys->open("/dev/consctl", sys->OWRITE);	if (cctlfd == nil)	{		return (-1, sys->sprint("Could not open /dev/consctl : %r"));	}	sys->write(cctlfd, array of byte "rawon", len "rawon"); 	consfd = sys->open("/dev/cons", sys->OREAD);	if (consfd == nil)	{		return (-1, sys->sprint("Could not open /dev/cons : %r"));	} 	filebuf := bufio->open(filename, sys->OREAD);	if (filebuf == nil)	{		return (-1, sys->sprint("Could not open [%s] : %r", filename));	} 	#	Determine number of lines in input file	numlines = 0;	while (filebuf.gets('\n') != nil)	{		numlines++;	} 	filebuf = bufio->open(filename, sys->ORDWR);	lines = array [numlines+1] of Line;	numlines = 0; 	while ((tmpstr = filebuf.gets('\n')) != nil)	{		lines[numlines].str = cleanends(tmpstr);		lines[numlines].ntabs = counttabs(tmpstr);		numlines++;	} 	#	Peruse mode by default	mode = 'P'; 	sys->fprint(stdout, "\n\nFile [%s], [%d] lines total\n\n",				filename, numlines);	sys->fprint(stdout, "[0][P]%s", lines[curlineidx].str);	cursoridx = len lines[curlineidx].str; 	while (sys->read(consfd, buf, 1) == 1)	{		key = int buf[0];		case (key | (mode << 8))		{			#	Ctrl-d : Exit			KEY_CTRLD =>			{				sys->fprint(stdout, "\n\n");				return (0, "");			} 			#	"s" or ENTER in peruse mode : Next line				KEY_S or KEY_PNEWLINE =>			{				if (curlineidx < numlines-1)				{					tmp := "[" + string curlineidx + "][ ]";					clear(len lines[curlineidx].str + len tmp +						lines[curlineidx].ntabs*(TABLEN-1)); 					curlineidx++; 					sys->fprint(stdout, "[%d][%c]%s",						curlineidx, mode, lines[curlineidx].str);				}			} 			#	ENTER in edit mode			KEY_ENEWLINE =>			{				if (curlineidx < numlines-1)				{					tmp := "[" + string curlineidx + "][ ]";					clear(len lines[curlineidx].str + len tmp +						lines[curlineidx].ntabs*(TABLEN-1)); 					curlineidx++; 					sys->fprint(stdout, "[%d][%c]%s",						curlineidx, mode, lines[curlineidx].str);				}				else				{					#insert_line(lines, cur_line_index);				}			} 			#	'a' : Previous line			KEY_A =>			{				if ((curlineidx > 0) && mode != 'E' )				{					tmp := "[" + string curlineidx + "][ ]";					clear(len lines[curlineidx].str + len tmp +						lines[curlineidx].ntabs*(TABLEN-1)); 					curlineidx--; 					sys->fprint(stdout,"[%d][%c]%s",						curlineidx, mode, lines[curlineidx].str);				}			} 			#	ESC : Toggle edit mode			KEY_PESC or KEY_EESC =>			{				if (mode == 'P')				{					mode = 'E';				}				else				{					mode = 'P';				} 				tmp := "[" + string curlineidx + "][ ]";                                clear(len lines[curlineidx].str + len tmp +						lines[curlineidx].ntabs*(TABLEN-1)); 				sys->fprint(stdout, "[%d][%c]%s",					curlineidx, mode, lines[curlineidx].str);				cursoridx = len lines[curlineidx].str;			} 			#	Save			KEY_DOT =>			{				save(filebuf, lines);			} 			#	Backspace			KEY_BACKSPACE =>			{				if (cursoridx >= 1)				{					sys->fprint(stdout,"\b");					cursoridx--;				}			} 			#	Tabs			KEY_TAB =>			{				sys->fprint(stdout, "%c", TABCHAR);				lines[curlineidx].str[cursoridx] = key;				cursoridx++;			}							#	List lines			KEY_L =>			{				cctlfd = nil;				cctlfd = sys->open("/dev/consctl", sys->OWRITE); 				sys->seek(cctlfd,0, sys->SEEKSTART);				sys->write(cctlfd, array of byte "rawoff", len "rawoff"); 				lbuf := array [Sys->ATOMICIO] of byte; 				sys->fprint(stdout,"\nLines to List: ");				sys->read(stdin, lbuf, len lbuf); 				(n, llist) := sys->tokenize(string lbuf, " \n\r"); 				if ( (int hd llist > numlines) || 					(int hd llist < 0) || 					(int hd tl tl llist > numlines) ||					(int hd tl tl llist < int hd llist) ||					(hd tl llist != "-") 				   )				{					if (hd tl llist != "-")					{							sys->fprint(stdout, "Wrong Format : \"%s\"\n",							string lbuf);					}					else					{						sys->fprint(stdout,							"Out of range. File Contains %d lines.\n",							numlines);						sys->fprint(stdout, "[%d][%c]%s",							curlineidx, mode, lines[curlineidx].str);					}				}				else				{					start := int hd llist;					finish := int hd tl tl llist; 					sys->fprint(stdout,"\n\n");					for (i := start; i <= finish; i++)					{						sys->fprint(stdout, "%s\n","|"+ string i +"> "+							lines[i].str);					}					sys->fprint(stdout,"\n\n");					sys->fprint(stdout,"[%d][%c]%s",							curlineidx, mode, lines[curlineidx].str);				}				sys->seek(cctlfd,0, sys->SEEKSTART);				sys->write(cctlfd, array of byte "rawon", len "rawon");			} 			KEY_N =>			{				sys->fprint(stdout,					"\n\nFile Contains %d lines total.\n\n",					numlines);				sys->fprint(stdout, "[%d][%c]%s",					curlineidx, mode, lines[curlineidx].str);			} 			* =>			{				if (mode == 'E')				{					if (cursoridx < len lines[curlineidx].str)					{						lines[curlineidx].str[cursoridx] = key;					}					else					{						lines[curlineidx].str[len lines[curlineidx].str]							= key;					} 					cursoridx++;					sys->fprint(stdout,"%c", key);				}			}		}	}	sys->fprint(stdout,"\n"); 	return (0, "");} cleanends(tmpstr : string) : string{	CR := max(len tmpstr - 2, 0);	LF := max(len tmpstr - 1, 0); 	if (tmpstr[CR] == '\r')	{		return tmpstr[: CR];	}	else if (tmpstr[LF] == '\n')	{		return tmpstr[: LF];	} 	return tmpstr;} counttabs(line : string) : int{	ntabs := 0; 	for (i := 0; i < len line; i++)	{		if (line[i] == '\t') ntabs++;	} 	return ntabs;} clear(delwidth : int){	delete := string (array [delwidth] of {* => byte '\b'});	blank := string (array [delwidth] of {* => byte ' '});	sys->print("%s", delete);	sys->print("%s", blank);	sys->print("%s", delete);} save(filebuf : ref Iobuf, lines : array of Line){	filebuf.seek(0, 0);        for (i := 0; i < numlines; i++)	{		#	We had stripped the newlines of the ends		if (lines[i].str == "\n")		{                	filebuf.puts(lines[i].str);		}		else		{			filebuf.puts(lines[i].str+"\n");		}        }	filebuf.flush(); 	tmp := "[" + string curlineidx + "][ ]";	clear(len lines[curlineidx].str + len tmp +		lines[curlineidx].ntabs*(TABLEN-1)); 	sys->fprint(stdout, "[%d][%c]%s",		curlineidx, 'S', lines[curlineidx].str);} max(a, b : int) : int{	if (a > b)	{		return a;	} 	return b;}