How to turn a floating point number into a string in ATS? - ats

Basically, I am looking for a function of the following interface:
fun double2string(x: double): string
which converts a double into a string representation for it. For instance, double2string(3.14) should return "3.14".

Sometimes I choose following cheat:
#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"
%{^
#include <assert.h>
char *double2string(double x) {
#define DECIMAL 8
#define DECIMAL_FORMAT "%.8e"
#define DECIMAL_LEN DECIMAL+2+5
char *s = malloc(DECIMAL_LEN+1);
assert(NULL != s);
memset(s, 0, DECIMAL_LEN+1);
snprintf(s, DECIMAL_LEN, DECIMAL_FORMAT, x);
return s;
}
%}
extern fun double2string (x: double): strptr = "mac#"
implement main0 () = {
val s = double2string 1234567890.1234567890
val () = println! s
val () = free s
}

There is a function of the name atspre_string_make_snprintf in ATSLIB for constructing strings. For instance, one can do:
#include
"share/atspre_staload.hats"
fun
double2string(x: double): string =
$extfcall
(
string, "atspre_string_make_snprintf", "%.8e", x
) (* double2string *)
implement
main0() =
println! ("Pi = ", double2string(3.1415926535))
What is returned by atspre_string_make_snprintf is a linear string (strptr), which can be freed:
fun double2strptr(x: double): Strptr1 = $extfcall(...)
When compiling, please remember to pass the flag -latslib. You can try this example on-line:
https://glot.io/snippets/ejm6ous1fh

For compiling to JavaScript, 'String' can be called to do this. Actually, 'String' turns any given object into some form string representation for it.

Here is a quick way to do it:
fun
double2string
(
x0: double
) : string = let
val i0 = g0float2int_double_int(x0)
val d0 = g0float2int_double_int(100000000 * (x0 - i0))
val i0_rep = g0int2string(i0)
val d0_rep = g0int2string(d0)
val x0_rep =
string0_append3
($UNSAFE.strptr2string(i0_rep), ".", $UNSAFE.strptr2string(d0_rep))
// end of [val]
val ((*freed*)) = strptr_free(i0_rep)
val ((*freed*)) = strptr_free(d0_rep)
in
strptr2string(x0_rep)
end // end of [double2string]

Related

How do you perfectly hash a union of a possibly unicode char with a 32-bit integer?

I've never really had the need to create hash function before but right now it seems like the best solution for this.
I haven't tried anything, but I guess what I would try first is to hash take the unicode integer as the least significant 32-bits of a long. Then in the most significant 32-bits, store the integer.
struct Symbol
{
private:
enum Type {
Terminal,
Variable,
}
union {
char m_term;
int m_var;
}
Type m_type;
public:
this(char term) {
m_type = Type.Terminal;
m_term = term;
}
this(int var) {
m_type = Type.Variable;
m_var = var;
}
}
Symbol is the struct I'd like to hash. It contains a union which we should hash to achieve this. Was just wondering if my approach above is correct.
Thanks to commenters.
bool opEquals(Symbol sym) const {
if (m_type == Type.Terminal)
return m_term == sym.m_term;
else
return m_var == sym.m_var;
}
ulong toHash() {
ulong bit = m_type;
ulong key;
if (m_type == Type.Terminal)
key = cast(ulong) m_term;
else
key = m_var;
return bit | (key << 1);
}

How are strings freed in ATS2?

http://www.ats-lang.org/Documents.html includes "Introduction to Programming in ATS", which includes the assertion that fileref_get_line_string returns a Strptr1 (a look in filebas.dats shows that it returns a String via strptr2string), and it includes this code:
#include "share/atspre_staload.hats"
#include "share/atspre_staload_libats_ML.hats"
implement main0() = loop() where
fun loop(): void = let
val isnot = fileref_isnot_eof(stdin_ref)
in
if isnot then let
val line = fileref_get_line_string(stdin_ref)
val () = print_string(line)
val () = strptr_free(line)
in
loop()
end else ()
end
end
Which throws a type error if the strptr_free line is included. If that line isn't included, the program blatantly leaks memory. Is there current documentation or are there ATS2 examples that show how the fileref_* words are supposed to be used? What is the ATS2 version of the code above?
There are two versions of fileref_get_line_string: one in prelude/filebas and
the other in libats/ML/filebas. For getting linear strings, you need
the former:
#include
"share/atspre_staload.hats"
implement
main0() = loop() where
fun
loop(): void = let
val
isnot =
fileref_isnot_eof(stdin_ref)
in
if isnot then let
val line =
fileref_get_line_string(stdin_ref)
val () =
print_strptr(line)
val () = free(line)
in
loop()
end else ()
end
end

Char vector is modified on copying character in C++

Following is my submission for
https://leetcode.com/problems/letter-combinations-of-a-phone-number
However I see very weird behavior on lines
char c = map1[s[i]][j];
t.replace(i,1,1,c);
The vector map1[s[i]] is changing size on execution of above line in the code below. How can character c be copied by value rather than reference. If I remove reference for string in function argument (meaning no &) everything works fine but it won't be the right way, since copying string by value is costly.
class Solution {
public:
string s;
vector<string> res;
unordered_map<char, vector<char>> map1;
void letterCombinations(string &t, int i){
char c;
if(s.size()==0)
return;
if(i==s.size())
res.push_back(t);
else{
for(int j=0;j<map1[s[i]].size();j++){
//cout<<"Starting:"<<map1[s[i]].size()<<endl;
char c = map1[s[i]][j];
t.replace(i,1,1,c);
letterCombinations(t, i+1);
//cout<<"Return:"<<map1[s[i]].size()<<endl;
}
}
}
vector<string> letterCombinations(string digits) {
stringstream t;
map1['1'] = vector<char>{};
map1['0'] = vector<char>{};
map1['2'] = vector<char>{'a','b','c'};
map1['3'] = vector<char>{'d','e','f'};
map1['4'] = vector<char>{'g','h','i'};
map1['5'] = vector<char>{'j','k','l'};
map1['6'] = vector<char>{'m','n','o'};
map1['7'] = vector<char>{'p','q','r','s'};
map1['8'] = vector<char>{'t','u','v'};
map1['9'] = vector<char>{'w','x','y','z'};
s=digits;
letterCombinations(s,0);
return res;
}
};

How to read user input in ATS?

In my ATS application, I am trying to read a input string from a user.
Is there any function in ATS that performs similar functionality as scanf function in C.. If not how to get the input from user without integrating ATS with JS or HTML.
Here is a simple way to read from STDIN:
#include
"share/atspre_staload.hats"
#include
"share/HATS/atspre_staload_libats_ML.hats"
implement
main0() =
{
//
val
lines =
streamize_fileref_line(stdin_ref)
//
val () = lines.foreach()(lam x => println! (x))
//
} (* end of [main0] *)
If you compile to C, then scanf is available. Here is a simple example:
#include
"share/atspre_staload.hats"
#staload
"libats/libc/SATS/stdio.sats"
implement
main0() =
{
//
var str1 = #[char][1024]()
var str2 = #[char][1024]()
//
val () = println! ("Enter name: ")
val ec = $extfcall(int, "scanf", "%s", addr#str1)
val () = assertloc (ec != 0)
val str1 = $UNSAFE.cast{string}(addr#str1)
//
val () = println! ("Enter your website name: ")
val ec = $extfcall(int, "scanf", "%s", addr#str2)
val () = assertloc (ec != 0)
val str2 = $UNSAFE.cast{string}(addr#str2)
//
val () = println! ("str1 = ", str1)
val () = println! ("str2 = ", str2)
//
}

Swift 1.2, capture character from a word

My problem is how to get character from a word
The result I needed is
DisplayChar("asd",1)
and it will display "a"
func DisplayChar(word : String, number : Int) -> String{
let i: Int = count(word)
var result = 0
result = i - (i - number)
var str = ""
var j = 0
for j = 0; j < result; j++ {
str = str + word[j]
}
return str
}
DisplayChar("xyz", 2)
This code should work
let sentence = "Hello world"
let characters = Array(sentence)
print(characters[0]) // "H"
There are a couple good solutions in this answer that may work, two good ones duplicated below.
Convert to Array
let word = "test"
var firstChar = Array(word)[0] // t
(Note: this assumes a UTF8 or ASCII encoded string, but that is likely fine for school.)
Create Your Own Extension
First an extension of String to handle subscripts:
extension String {
subscript (i: Int) -> Character {
return self[self.startIndex.advancedBy(i)]
}
subscript (i: Int) -> String {
return String(self[i] as Character)
}
subscript (r: Range<Int>) -> String {
let start = startIndex.advancedBy(r.startIndex)
let end = start.advancedBy(r.endIndex - r.startIndex)
return self[Range(start ..< end)]
}
}
Then you can just use:
let word = "test"
var firstChar = word[0] // t
Swift strings have a method called substringToIndex, "asd".substringToIndex(1) will return "a".
I'm not sure if it works on Swift 1.2, though.

Resources