poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] More powerful string literals, instead of new format function


From: Mohammad-Reza Nabipoor
Subject: [RFC] More powerful string literals, instead of new format function
Date: Sat, 13 Mar 2021 00:13:07 +0330

Hi.

I think that it'd be a good idea to have more powerful string literals,
instead of having a printf-like function (the `format` function).

Syntactically, it's more compact and simpler to read.
And also more useful for (future) inline asm statements.

Let's have a look at other languages; I chose two languages to look at:
Python and Kotlin.


=== String interpolation in other languages

```kotlin
val name = "John"
val age = 19
val msg = "$name is $age years old"

assert(msg == "John is 19 years old")

val a = 2
val b = 3
val res = "a*b: ${a*b}"

assert(res == "a*b: 6")
```

```python3
name = "John"
age = 19
msg = f"{name} is {age} years old"

assert msg == "John is 19 years old"

a = 2
b = 3
res = f"a*b: {a*b}"

assert res == "a*b: 6"

assert f"{{70 + 4}}" == "{70 + 4}"  # No interpolation
```


=== Proposal for Poke

I propose a Python-like string literal: f-strings.
Let's talk in code:

```poke
var x = 100;
var y = 0xabUL;

/* printf ("%v and %v", x, y) */
var str1 = f"{x} and {y}";

assert(str1 == "0x00000064 and 0x00000000000000abUL");

/* printf ("%i32d is a signed integer. %u64x is an unsigned integer.", x, y) */
var str2 = f"{x:i32d} is a signed integer. {y:u64x} is an unsigned integer.";

assert(
  str2 == "100 is a signed integer. 00000000000000ab is an unsigned integer");

/* printf ("Array: %v\n") */
var A = [1,2,3];
var str3 = f"Array: {A}";

assert(str3 == "Array: [1,2,3]\n");

/* Adding more stuff to strings: fat strings */

/* TAG,CLASS */
var fat_str_1 = f"Styled integer: {x:i32d,integer}";

assert(fat_str_1 == "Styled integer: 100");
print (fat_str_1);
/* HTML output: */
/* Styled&nbsp;integer:&nbsp;<span class="integer">100</span> */


var hyper_text = "Click me";
var hyper_id = "";
var hyper_url = "app://ankh-morpok:46603/1161/e/.help";
var hyper_arr = [hyper_text, hyper_id, hyper_url];

var fat_str_2_1 = f"Hyperlink: {hyper_arr:h}";

/* or, we can write the array inline: */
var fat_str_2_2 = f"Hyperlink: {[hyper_text, hyper_id, hyper_url]:h}";

/* or, */
var fat_str_2_3 = 
  f"Hyperlink: {["Click me", "", "app://ankh-morpok:46603/1161/e/.help"]:h}";

/* `h` tag requires an array of type `string[3]` */

assert(fat_str_2_1 == fat_str_2_2 == fat_str_2_3 == "Hyperlink: Click me");


fun fun1 = void:
  {
    /* do something */
  }
fun fun2 = (int i) void:
  {
    /* do something */
  }

/* l,STRING */
/* l,{EXPR} */
var fat_str_3_1 = f"Lambda: {(fun1):l,Click me}"; /* `l` stands for lambda */
var fat_str_3_2 = f"Labmda: {(fun1):l,{hyper_text}}";
var fat_str_3_3 = f"Labmda: {fun2:l,{"Click" + " " + "me"}}";

assert(fat_str_3_1 == "Lambda: Click me");

/* To write `{` we can use `{{` */
assert(f"No interpolation: {{2*3}}" == "No interpolation: {2*3}");
```

=== asm statements

f-strings are useful in future `asm` statements.

```poke
var fname = "f";
var inc = 1;
asm("
      note    \"{fname}\"
$L1:  prolog
      pushf   0
      pushf   1
      push    0x1
      regvar
      pushvar 0x0, 0x0
      push    {inc}
      addi
      nip2
      popvar  0x0, 0x0
      pushvar 0x0, 0x0
      return
      popf    1
      push    Exception {{code=0x3,msg=\"no return\",exit_status=0x1}}
      raise
      return
");
```

=== Final notes

- The validity of string interpolation can be verified at compile-time.
- I think `==` for strings should remain as it is, and should not consider
  the metadata.


Suggestions?
Simplifications to proposed syntax?


Regards,
Mohammad-Reza


reply via email to

[Prev in Thread] Current Thread [Next in Thread]