hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

dump.ha (1980B)


      1 // License: MPL-2.0
      2 // (c) 2022 Sebastian <sebastian@sebsite.pw>
      3 use fmt;
      4 use io;
      5 use strings;
      6 use strio;
      7 
      8 // Dumps a [[value]] into an [[io::handle]] as a string without any additional
      9 // formatting.
     10 export fn dump(out: io::handle, val: value) (size | io::error) = {
     11 	let z = 0z;
     12 	match (val) {
     13 	case let v: (f64 | bool) =>
     14 		z += fmt::fprint(out, v)?;
     15 	case let s: str =>
     16 		z += fmt::fprint(out, `"`)?;
     17 		let it = strings::iter(s);
     18 		for (true) match (strings::next(&it)) {
     19 		case void =>
     20 			break;
     21 		case let r: rune =>
     22 			switch (r) {
     23 			case '\b' =>
     24 				z += fmt::fprint(out, `\b`)?;
     25 			case '\f' =>
     26 				z += fmt::fprint(out, `\f`)?;
     27 			case '\n' =>
     28 				z += fmt::fprint(out, `\n`)?;
     29 			case '\r' =>
     30 				z += fmt::fprint(out, `\r`)?;
     31 			case '\t' =>
     32 				z += fmt::fprint(out, `\t`)?;
     33 			case '\"' =>
     34 				z += fmt::fprint(out, `\"`)?;
     35 			case '\\' =>
     36 				z += fmt::fprint(out, `\\`)?;
     37 			case =>
     38 				if (iscntrl(r)) {
     39 					z += fmt::fprintf(out, `\u{:04x}`,
     40 						r: u32)?;
     41 				} else {
     42 					z += fmt::fprint(out, r)?;
     43 				};
     44 			};
     45 		};
     46 		z += fmt::fprint(out, `"`)?;
     47 	case _null =>
     48 		z += fmt::fprint(out, "null")?;
     49 	case let a: []value =>
     50 		z += fmt::fprint(out, "[")?;
     51 		for (let i = 0z; i < len(a); i += 1) {
     52 			z += dump(out, a[i])?;
     53 			if (i < len(a) - 1) {
     54 				z += fmt::fprint(out, ",")?;
     55 			};
     56 		};
     57 		z += fmt::fprint(out, "]")?;
     58 	case let o: object =>
     59 		z += fmt::fprint(out, "{")?;
     60 		let comma = false;
     61 		let it = iter(&o);
     62 		for (true) match (next(&it)) {
     63 		case void => break;
     64 		case let pair: (const str, const *value) =>
     65 			if (comma) {
     66 				z += fmt::fprint(out, ",")?;
     67 			};
     68 			comma = true;
     69 			z += dump(out, pair.0)?;
     70 			z += fmt::fprint(out, ":")?;
     71 			z += dump(out, *pair.1)?;
     72 		};
     73 		z += fmt::fprint(out, "}")?;
     74 	};
     75 	return z;
     76 };
     77 
     78 // Dumps a [[value]] into a string without any additional formatting. The caller
     79 // must free the return value.
     80 export fn dumpstr(val: value) str = {
     81 	let s = strio::dynamic();
     82 	dump(&s, val)!;
     83 	return strio::string(&s);
     84 };