[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 integer: <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
- [RFC] More powerful string literals, instead of new format function,
Mohammad-Reza Nabipoor <=