I'm getting close to converting felix over to using the Show typeclass to handle string conversion. I'm about to go to bed, but I wanted to show what I've got, and maybe get some suggestions before I integrate the code. Anyway, check it out if you got some free time.

I wish there was a way to have printing of arbitrarily long tuples, but that probably requires a ton of work with no clear idea how to do it. I'll probably make typeclasses for 1 through 16 like haskell, and then see if I can get the array to do 17+. Not sure yet how to do that yet.

-e


#import "show.flx"

proc p[T with Show2[T]] (t:T) {
  var x = t;
  print $ "type: " + Debug::repr_type[T]; endl;
  print $ "str:  " + (str2 x); endl;
  print $ "repr: " + (repr2 x); endl;
  endl;
}

p true;
p 1t;
p 1ut;
p 1s;
p 1us;
p 1;
p 1u;
p 1l;
p 1ul;
p 1v;
p 1uv;

// to dodge c++'s divide-by-zero check
val fzero = 0.0f;
val dzero = 0.0;
val ldzero = 0.0l;

p 1.0f;
p 1.5f;
p (0.0f/fzero);
p (1.0f/fzero);
p (-1.0f/fzero);

p 1.0;
p (0.0/dzero);
p (1.0/dzero);
p (-1.0/dzero);

p 1.0l;
p (0.0l/ldzero);
p (1.0l/ldzero);
p (-1.0l/ldzero);

p $ char 'a';
p $ wchar 97l;
p $ uchar $ 97u;

p $ C_hack::cast[byte] 1t;
p $ C_hack::cast[address] 16ul;
p $ C_hack::cast[caddress] 16ul;
p $ C_hack::cast[vaddress] 16ul;
p $ C_hack::cast[cvaddress] 16ul;
p $ C_hack::cast[offset] 16ul;

p "Domo Arigato,\n\tMr Roboto!";
//p u"Domo Arigato,\n\tMr Roboto!";

p $ List::list(1,2,3);
p $ List::list("a","b","c");

// can't have the same number of template and array typeclasses
p $ (1,2,3,4);
p $ (1,2,3,4,5);
p $ (1,2,3,4,5,6);
p $ (1,"b");
p $ (1,"b",1.0);
#import <flx.flxh>

typeclass Str2[T] {
  virtual fun str2: T -> string;
}

typeclass Repr2[T with Str2[T]] {
  virtual fun repr2 (t:T) : string => str2 t;
}

typeclass Show2[T] {
  inherit Str2[T];
  inherit Repr2[T];
}

proc print2[T with Show2[T]] (t:T) {
  fprint (Stdout::cout, str2 t);
}

//////////////////////////////////////////////////////////////////////////////

instance Str2[bool] {
  fun str2 (x:bool) => if x then "true" else "false" endif;
}

instance Str2[tiny] {
  fun str2: tiny -> string = "flx::rtl::strutil::str<int>($1)" requires 
flx_strutil;
}

instance Repr2[tiny] {
  fun repr2 (t:tiny) : string => (str2 t) + "t";
}

instance Str2[utiny] {
  fun str2: utiny -> string = "flx::rtl::strutil::str<unsigned int>($1)" 
requires flx_strutil;
}

instance Repr2[utiny] {
  fun repr2 (t:utiny) : string => (str2 t) + "ut";
}

instance[T in short||ushort||int||uint||long||ulong||vlong||uvlong] Str2[T] {
  fun str2: T -> string = "flx::rtl::strutil::str<#1>($1)" requires flx_strutil;
}

instance Repr2[short] {
  fun repr2 (t:short) : string => (str2 t) + "s";
}

instance Repr2[ushort] {
  fun repr2 (t:ushort) : string => (str2 t) + "us";
}

instance Repr2[uint] {
  fun repr2 (t:uint) : string => (str2 t) + "u";
}

instance Repr2[long] {
  fun repr2 (t:long) : string => (str2 t) + "l";
}

instance Repr2[ulong] {
  fun repr2 (t:ulong) : string => (str2 t) + "ul";
}

instance Repr2[vlong] {
  fun repr2 (t:vlong) : string => (str2 t) + "v";
}

instance Repr2[uvlong] {
  fun repr2 (t:uvlong) : string => (str2 t) + "uv";
}

fun format_real (t:ldouble, precision:int, suffix:string) : string = {
  val s = vsprintf (f"%%.%ig" precision, t);
  return
    regmatch s with
    | ["0" - "9"]+ => { s + ".0" + suffix }
    | ["0" - "9"]+ "." ["0" -"9"]+ => { s + suffix }
    | _* => { s }
    endmatch ()
  ;
}

instance Str2[float] {
  fun str2 (t:float) : string => format_real (ldouble t, 12, "");
}

instance Str2[double] {
  fun str2 (t:double) : string => format_real (ldouble t, 12, "");
}

instance Str2[ldouble] {
  fun str2 (t:ldouble) : string => format_real (t, 12, "");
}

/*
instance[T in float||double||ldouble] Str2[T] {
  fun str2 (t:T) : string => format_real (C_hack::static_cast[ldouble] (t), 12, 
"");
}
*/

instance Repr2[float] {
  fun repr2 (t:float) : string => format_real (ldouble t, 17, "f");
}

instance Repr2[double] {
  fun repr2 (t:double) : string => format_real (ldouble t, 17, "");
}

instance Repr2[ldouble] {
  fun repr2 (t:ldouble) : string => format_real (t, 17, "l");
}

instance[T in chars] Str2[T] {
  fun str2: T -> string = "flx::rtl::strutil::str<#1>($1)" requires flx_strutil;
}

instance Repr2[char] {
  fun repr2 (c:char) : string = {
    val s = str2 c;
    return
      match s with
      | "'"  => "\\'"
      | '\t' => '\\t'
      | '\n' => '\\n'
      | '\r' => '\\r'
      | '\f' => '\\f'
      | '\v' => '\\v'
      | _    => s
      endmatch
    ;
  }
}

instance[T in addressing] Str2[T] {
  fun str2 (t:T) : string => vsprintf (c"%i", t);
}

/*
instance[T in addressing] Repr2[T] {
  fun repr2 (t:T) : string => vsprintf (c"0x%x", t);
}
*/

open[T in basic_types] Show2[T];

/////////////////////////////////////////////////////////////////////////////

instance Str2[string] {
  fun str2 (x:string) : string => x;
}

instance Repr2[string] {
  fun repr2 (x:string) : string = {
    var o = "'";
    var i: int; forall i in 0 upto (len x) - 1 do
      o += repr2 x.[i];
    done;
    return o + "'";
  }
}

/*
bug if we allow this
instance Str2[ustring] {
  fun str2 (x:ustring) : string => string x;
}
*/

open[T in string||ustring] Show2[T];

instance[T with Show2[T]] Str2[List::list[T]] {
  fun str2 (xs:List::list[T]) =>
    '[' +
      match xs with
      | Empty[T] => ''
      | Cons(?o, ?os) =>
          List::fold_left (
            fun (a:string) (b:T):string => a + ', ' + (repr2 b)
          ) (repr2 o) os
      endmatch
    + ']'
  ;
}
open[T] Show2[List::list[T]];

instance[T,N with Show2[T]] Str2[Array::array[T,N]] {
  fun str2 (xs:array[T,N]) = {
    var o = '[|' + str2 xs.[0];
    var i : int;

    forall i in 1 upto len(xs) - 1 do
      o += ', ' + str2 xs.[i];
    done;

    return o + '|]';
  }
}
open[T,N] Show2[Array::array[T,N]];

instance[A,B with Show2[A], Show2[B]] Str2[A*B] {
  fun str2 (a:A, b:B):string =>
    '(' + (repr2 a) + ', ' + (repr2 b) + ')'
  ;
}

instance[A,B,C with Show2[A], Show2[B], Show2[C]] Str2[A*B*C] {
  fun str2 (a:A, b:B, c:C):string =>
    '(' + (repr2 a) + ', ' + (repr2 b) + ', ' + (repr2 c) + ')'
  ;
}

open[A,B] Show2[A*B];
open[A,B,C] Show2[A*B*C];
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to