Charles.Forsyth20060303a828770d19 years agoHistory
246 lines · 4.6 KB · Brainfuck
RawDownload
implement TclLib; include "sys.m";	sys: Sys;include "draw.m";include "tk.m";include "bufio.m";	bufmod : Bufio;Iobuf : import bufmod; include "string.m";	str : String;include "tcl.m";include "tcllib.m"; error : int;started : int;valid_commands:=array[] of {"format","string"}; about() : array of string{	return valid_commands;} init(){	started=1;	sys=load Sys Sys->PATH;} exec(tcl : ref Tcl_Core->TclData,argv : array of string) : (int,string) {	if (tcl.context==nil);	if (!started) init();	error=0;	str=load String String->PATH;	if (str==nil)		return(1,"String module not loaded.");	if (len argv==1 && argv[0]=="string")		return (error,			notify(1,"string option arg ?arg ...?"));	case argv[0]{		"format" =>			return (error,do_format(argv));		"string" =>			return (error,do_string(argv));	}	return (1,nil);}  do_string(argv : array of string) : string{	case argv[1]{		"compare" =>			if (len argv == 4){				i:= - (argv[2]<argv[3])+ (argv[2]>argv[3]);				return string i;			}			return notify(1,			     "string compare string1 string2");		"first" =>			return nil;		"last" =>			return nil;		"index" =>			if (len argv == 4){				if (len argv[2] > int argv[3])					return argv[2][int argv[3]:int argv[3]+1];				return nil;			}			return notify(1,			     "string index string charIndex");		"length" =>			if (len argv==3)				return string len argv[2];			return notify(1,"string length string");		"match" =>			return nil;		"range" =>			if (len argv==5){				end :int;				if (argv[4]=="end") 					end=len argv[2];				else					end=int argv[4];				if (end>len argv[2]) end=len argv[2];				beg:=int argv[3];				if (beg<0) beg=0;				if (beg>end)					return nil;				return argv[2][int argv[3]:end];			}			return notify(1,			     "string range string first last");		"tolower" =>			if (len argv==3)				return str->tolower(argv[2]);			return notify(1,"string tolower string");		"toupper" =>			if (len argv==3)				return str->tolower(argv[2]);			return notify(1,"string tolower string");		"trim" =>			return nil;		"trimleft" =>			return nil;		"trimright" =>			return nil;		"wordend" =>			return nil;		"wordstart" =>			return nil;	}	return nil;} do_format(argv : array of string) : string {	retval,num1,num2,rest,curfm : string;	i,j : int;	if (len argv==1)		return notify(1,			"format formatString ?arg arg ...?");	j=2;	i1:=-1;	i2:=-1;	(retval,rest)=str->splitl(argv[1],"%");	do {		(curfm,rest)=str->splitl(rest[1:],"%");		i=0;		num1="";		num2="";		if (curfm[i]=='-'){			num1[len num1]=curfm[i];			i++;		}		while(curfm[i]>='0' && curfm[i]<='9'){			num1[len num1]=curfm[i];			i++;		}		if (num1!="")			(i1,nil) = str->toint(num1,10);		if (curfm[i]=='.'){			i++;			while(curfm[i]>='0' && curfm[i]<='9'){				num2[len num2]=curfm[i];				i++;			}			(i2,nil) = str->toint(num2,10);		} else {			i2=i1;			i1=-1;		}		case curfm[i] {			's' =>				retval+=print_string(i1,i2,argv[j]);			'd' => 				retval+=print_int(i1,i2,argv[j]);			'f' =>				retval+=print_float(i1,i2,argv[j]);			'x' =>				retval+=print_hex(i1,i2,argv[j]);		}		j++;	} while (rest!=nil && j<len argv);	return retval;} notify(num : int,s : string) : string {	error=1;	case num{		1 =>			return sys->sprint(			"wrong # args: should be \"%s\"",s);		* =>			return s;	}} print_string(i1,i2 : int, s : string) : string {	retval : string;	if (i1==-1 && i2==-1)		retval=sys->sprint("%s",s);	if (i1==-1 && i2!=-1)		retval=sys->sprint("%*s",i1,s);	if (i1!=-1 && i2!=-1)		retval=sys->sprint("%*.*s",i1,i2,s);	if (i1!=-1 && i2==-1)		retval=sys->sprint("%.*s",i2,s);		return retval;} print_int(i1,i2 : int, s : string) : string {	retval,ret2 : string;	n : int;	(num,nil):=str->toint(s,10);	width:=1;	i:=num;	while((i/=10)!= 0) width++;	if (i2 !=-1 && width<i2) width=i2;	for(i=0;i<width;i++)		retval[len retval]='0';	while(width!=0){		retval[width-1]=num%10+'0';		num/=10;		width--;	}	if (i1 !=-1 && i1>i){		for(n=0;n<i1-i;n++)			ret2[len ret2]=' ';		ret2+=retval;		retval=ret2;	}	return retval;}  print_float(i1,i2 : int, s : string) : string {	r:= real s;	retval:=sys->sprint("%*.*f",i1,i2,r);	return retval;} print_hex(i1,i2 : int, s : string) : string {	retval,ret2 : string;	n : int;	(num,nil):=str->toint(s,10);	width:=1;	i:=num;	while((i/=16)!= 0) width++;	if (i2 !=-1 && width<i2) width=i2;	for(i=0;i<width;i++)		retval[len retval]='0';	while(width!=0){		n=num%16;		if (n>=0 && n<=9)			retval[width-1]=n+'0';		else			retval[width-1]=n+'a'-10;		num/=16;		width--;	}	if (i1 !=-1 && i1>i){		for(n=0;n<i1-i;n++)			ret2[len ret2]=' ';		ret2+=retval;		retval=ret2;	}	return retval;}