Strings

Priskribo de la ĉi-paĝa enhavo

Konvertado de Strings al pluri program-lingvoj.

Etikedoj:

Ĉi-tiu programo estas konvertita en 20 program-lingvojn.

Originalo

Origin of strings.bas:

Example included in Vintage BASIC 1.0.3.

http://vintage-basic.net/

10 INPUT"ENTER A STRING";A$
20 INPUT"ENTER A NUMBER";N
30 ?"ASC(A$)=";ASC(A$)
40 ?"CHR$(N)=";CHR$(N)
50 ?"LEFT$(A$,N)=";LEFT$(A$,N)
60 ?"MID$(A$,N)=";MID$(A$,N)
70 ?"MID$(A$,N,3)=";MID$(A$,N,3)
80 ?"RIGHT$(A$,N)=";RIGHT$(A$,N)
90 ?"LEN(A$)=";LEN(A$)
100 ?"VAL(A$)=";VAL(A$)
110 ?"STR$(N)=";STR$(N)
120 ?"SPC(N)='";SPC(N);"'"

En Arturo

; Strings

; Original version in BASIC:
;   Example included in Vintage BASIC 1.0.3.
;   http://www.vintage-basic.net

; This version in Arturo:
;   Copyright (c) 2023, Marcos Cruz (programandala.net)
;   SPDX-License-Identifier: Fair
;
; Written on 2023-10-18.
;
; Last modified: 20251205T0053+0100.

space: " "

s: input "Enter a string: "

until [
    dup try? [
        n: to :integer input "Enter an integer: "
    ]
    else [print "Integer expected. Retry."]
][]

print ""

prints ~"ASC(\"|s|\") --> "
prints ~"to :integer first \"|s|\" --> "
print to :integer first s

prints ~"CHR$(|n|) --> "
prints ~"to :string to :char |n| --> "
print to :string to :char n

prints ~"LEFT$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" 0 min range sub |n| 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s 0 min range sub n 1 sub size s 1|\""

prints ~"MID$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" min range sub |n| 1 sub size \"|s|\" 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s min range sub n 1 sub size s 1 sub size s 1|\""

prints ~"MID$(\"|s|\", |n|, 3) --> "
prints ~"slice \"s\" min range sub |n| 1 sub size \"|s|\" 1 min range add sub |n| 1 sub 3 1 sub size \"|s|\" 1 --> "
print ~"\"|slice s min range sub n 1 sub size s 1 min range add sub n 1 sub 3 1 sub size s 1|\""

prints ~"RIGHT$(\"|s|\", |n|) --> "
prints ~"slice \"|s|\" max range 0 sub size \"|s|\" |n| sub size \"|s|\" 1 --> "
print ~"\"|slice s max range 0 sub size s n sub size s 1|\""

prints ~"LEN(\"|s|\") --> "
prints ~"size \"|s|\" --> "
print size s

prints ~"VAL(\"|s|\") --> "
prints ~"if? numeric? \"|s|\" [to :floating \"|s|\"] else [0] --> "
print [ if? numeric? s [to :floating s] else [0] ]

prints ~"STR$(|n|) --> "
prints ~"to :string |n| --> "
print ~"\"|to :string n|\""

prints ~"SPC(|n|) --> "
prints ~"repeat \" \" |n| --> "
print ~"\"|repeat space n|\""

En C#

// Strings

// Original version in BASIC:
//  Example included in Vintage BASIC 1.0.3.
//  http://www.vintage-basic.net

// This version in C#:
//  Copyright (c) 2024, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written in 2024-12-21/25.
//
// Last modified: 20251205T1549+0100.

using System;

class vintageBasicStrings
{
    static string GetString(string prompt)
    {
        Console.Write(prompt);
        return Console.ReadLine();
    }

    static int GetInteger(string prompt)
    {
        int n = 0;

        while (true)
        {
            try
            {
                n = Int32.Parse(GetString(prompt));
                break;
            }
            catch
            {
            }
        }

        return n;
    }

    static void Main()
    {
        string s = GetString("Enter a string: ");
        int n = GetInteger("Enter an integer: ");

        Console.WriteLine();

        Console.Write($"ASC(\"{s}\") --> ");
        Console.Write($"(int) \"{s}\"[0] --> ");
        Console.WriteLine((int) s[0]);

        Console.Write($"CHR$({n}) --> ");
        Console.Write($"(char) ({n}) --> ");
        Console.WriteLine("'" + (char) n + "'");

        Console.Write($"LEFT$(\"{s}\", {n}) --> ");
        Console.Write($"\"{s}\".Substring(0, Math.Min({n}, \"{s}\".Length) --> ");
        Console.WriteLine("\"" + s.Substring(0, Math.Min(n, s.Length)) + "\"");

        Console.Write($"MID$(\"{s}\", {n}) --> ");
        Console.Write($"{n} > \"{s}\".Length ? \"\" : \"{s}\".Substring({n} - 1) --> ");
        Console.WriteLine("\"" + (n > s.Length ? "" : s.Substring(n - 1)) + "\"");

        Console.Write($"MID$(\"{s}\", {n}, 3) --> ");
        Console.Write($"{n} > \"{s}\".Length ? \"\" : \"{s}\".Substring({n} - 1, Math.Min(3, \"{s}\".Length - {n} + 1)) --> ");
        Console.WriteLine("\"" + (n > s.Length ? "" : s.Substring(n - 1, Math.Min(3, s.Length - n + 1)) + "\""));

        Console.Write($"RIGHT$(\"{s}\", {n}) --> ");
        Console.Write($"\"{s}\".Substring(Math.Max(0, \"{s}\".Length - {n}) --> ");
        Console.WriteLine("\"" + s.Substring(Math.Max(0, s.Length - n)) + "\"");

        Console.Write($"LEN(\"{s}\") --> ");
        Console.Write($"\"{s}\".Length --> ");
        Console.WriteLine(s.Length);

        Console.Write($"VAL(\"{s}\") --> ");
        int v;
        try{ v = Int32.Parse(s); } catch { v = 0; };
        Console.WriteLine($"int v; try{{ v = Int32.Parse(\"{s}\"); }} catch {{ v = 0; }} --> {v}");

        Console.Write($"STR$({n}) --> ");
        Console.Write($"Convert.ToString({n}) --> ");
        Console.WriteLine("\"" + Convert.ToString(n) + "\"");

        Console.Write($"SPC({n}) --> ");
        Console.Write($"new string(' ', {n}) --> ");
        Console.WriteLine("\"" + new string(' ', n) + "\"");
    }
}

En Chapel

// Strings

// Original version in BASIC:
//     Example included in Vintage BASIC 1.0.3.
//     http://www.vintage-basic.net

// This version in Chapel:
//     Copyright (c) 2025, Marcos Cruz (programandala.net)
//     SPDX-License-Identifier: Fair
//
// Written on 2025-04-06.
//
// Last modified: 20250407T1346+0200.

import IO;

proc acceptString(prompt: string): string {
    write(prompt);
    IO.stdout.flush();
    return IO.readLine().strip();
}

proc acceptValidInteger(prompt: string): int {
    var result: int;
    while true {
        var s: string = acceptString(prompt);
        try {
            result = (s): int;
            break;
        }
        catch exc {
            writeln("Integer expected.");
        }
    }
    return result;
}

proc main() {

    var s: string = acceptString("Enter a string: ");
    var n: int = acceptValidInteger("Enter an integer: ");

    writef(
        'ASC("%s") --> "%s"[0].toCodepoint() --> %i\n',
        s, s, s[0].toCodepoint()
    );
    writef(
        'CHR$(%i) --> codepointToString(%i: int(32)) --> "%s"\n',
        n, n, codepointToString(n: int(32))
    );
    writef(
        'LEFT$("%s", %i) --> "%s"[0 .. min(%i - 1, "%s".size - 1)] --> "%s"\n',
        s, n, s, n, s, s[0 .. min(n - 1, s.size - 1)]
    );
    writef(
        'MID$("%s", %i) --> "%s"[%i - 1 ..] --> "%s"\n',
        s, n, s, n, s[n - 1 ..]
    );
    writef(
        'MID$("%s", %i, 3) --> "%s"[%i - 1 .. min(%i - 1 + 3 - 1, "%s".size - 1)] --> "%s"\n',
        s, n, s, n, n, s, s[n - 1 .. min(n - 1 + 3 - 1, s.size - 1)]
    );
    writef(
        'RIGHT$("%s", %i) --> "%s"[max(0, "%s".size - %i) .. "%s".size - 1] --> "%s"\n',
        s, n, s, s, n, s, s[max(0, s.size - n) .. s.size - 1]
    );
    writef(
        'LEN("%s") --> "%s".size --> %i\n',
        s, s, s.size
    );
    var sToReal: real;
    try {
        sToReal = s: real;
        writef(
            'VAL("%s") --> "%s": real --> %r\n',
            s, s, sToReal
        );
    }
    catch ext {
        writef(
            'VAL("%s") --> "%s": real /* error catched by `catch` */ --> %r\n',
            s, s, sToReal
        );
    }
    writef(
        'STR$(%i) --> %i: string --> "%s"\n',
        n,n, n: string
    );
    writef(
        'SPC(%i) --> " " * %i --> "%s"',
        n, n, " " * n
    );

}

En Crystal

# Strings

# Original version in BASIC:
#     Example included in Vintage BASIC 1.0.3.
#     http://www.vintage-basic.net

# This version in Crystal:
#     Copyright (c) 2023, Marcos Cruz (programandala.net)
#     SPDX-License-Identifier: Fair
#
# Written in 2023-09.
#
# Last modified: 20241226T0148+0100.

def get_integer : Int
  while true
    print "Enter an integer: "
    begin
      return gets.not_nil!.to_i
      break
    rescue
      puts "That wasn't a valid integer."
    end
  end
end

print "Enter a string: "
s = gets.not_nil!
n = get_integer

print "ASC(\"#{s}\") --> "
print "\"#{s}\".[0].ord --> "
print s.[0].ord, "\n"

print "CHR$(#{n}) --> "
print "#{n}.chr --> "
print "'", n.chr, "'\n"

print "LEFT$(\"#{s}\", #{n}) --> "
print "\"#{s}\".[0...#{n}] --> "
print "\"", s.[0...n], "\"\n"

print "MID$(\"#{s}\", #{n}) --> "
print "\"s\".[#{n} - 1..] --> "
print "\"", s.[n - 1..], "\"\n"

print "MID$(\"#{s}\", #{n}, 3) --> "
print "\"s\".[(#{n} - 1)...(#{n} - 1 + 3)] --> "
print "\"", s.[(n - 1)...(n - 1 + 3)], "\"\n"

print "RIGHT$(\"#{s}\", #{n}) --> "
print "\"s\".[#{-n}..] --> "
print "\"", s.[-n..], "\"\n"

print "LEN(\"#{s}\") --> "
print "\"#{s}\".size --> "
print s.size, "\n"

print "VAL(\"#{s}\") --> "
print "(\"#{s}\".to_f rescue 0.0) --> "
print (s.to_f rescue 0.0), "\n"

print "STR$(#{n}) --> "
print "#{n}.to_s --> "
print "\"#{n.to_s}\"\n"

print "SPC(#{n}) --> "
print " \" \" * #{n} --> "
print "\"", (" " * n), "\"\n"

En D

// Strings

// Original version in BASIC:
//     Example included in Vintage BASIC 1.0.3.
//     http://www.vintage-basic.net

// This version in D:
//     Copyright (c) 2025, Marcos Cruz (programandala.net)
//     SPDX-License-Identifier: Fair
//
// Written in 2025-03-22/23.
//
// Last modified: 20251220T0653+0100.

module strings;

string acceptString(string prompt)
{
    import std.stdio : readln;
    import std.stdio : write;
    import std.string : strip;

    write(prompt);
    return strip(readln());
}

int acceptValidInteger(string prompt)
{
    import std.conv : to;
    import std.stdio : writeln;

    int result;
    while (true)
    {
        string s = acceptString(prompt);
        try
        {
            result = to!int(s);
            break;
        }
        catch (Exception exc)
        {
            writeln("Integer expected.");
        }
    }
    return result;
}

void main()
{
    import std.array : replicate;
    import std.conv : to;
    import std.range : repeat;
    import std.stdio : writefln;

    string s = acceptString("Enter a string: ");
    int n = acceptValidInteger("Enter an integer: ");

    writefln("ASC(\"%1$s\") --> to!(int)(\"%1$s\"[0]) --> %2$d", s, to!(int)(s[0]));
    writefln("CHR$(%1$d) --> to!char(%1$d) --> \"%2$s\"", n, to!char(n));
    writefln("LEFT$(\"%1$s\", %2$d) --> \"%1$s\"[0 .. %2$d] --> \"%3$s\"", s, n, s[0 .. n]); // XXX TODO utf-8
    writefln("MID$(\"%1$s\", %2$d) --> \"%1$s\"[%2$d - 1 .. \"%1$s\".length] --> \"%3$s\"", s, n, s[n - 1 .. s.length]); // XXX TODO utf-8
    writefln("MID$(\"%1$s\", %2$d, 3) --> \"%1$s\"[%2$d - 1 .. %2$d - 1 + 3] --> \"%3$s\"", s, n, s[n - 1 .. n - 1 + 3]); // XXX TODO utf-8
    writefln("RIGHT$(\"%1$s\", %2$d) --> \"%1$s\"[\"%1$s\".length - %2$d .. \"%2s\".length] --> \"%3$s\"", s, n, s[s.length - n .. s.length]); // XXX TODO utf-8
    writefln("LEN(\"%1$s\") --> \"%1$s\".length --> %2$d", s, s.length);
    writefln("VAL(\"%1$s\") --> to!(float)(\"%1$s\") --> %2$f", s, to!(float)(s)); // XXX TODO catch error
    writefln("STR$(%1$d) --> to!(string)(%1$d) --> \"%2$s\"", n, to!(string)(n));
    writefln("SPC(%1$d) --> repeat(' ', %1$d) --> \"%2$s\"", n, repeat(' ', n));
    writefln("SPC(%1$d) --> replicate(\" \", %1$d) --> \"%2$s\"", n, replicate(" ", n));
}

En Go

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Go:
    Copyright (c) 2024, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2024-12-29/30.

Last modified: 20250105T1151+0100.
*/

package main

import "fmt"
import "strconv"
import "strings"

func inputString(prompt string) string {

    fmt.Print(prompt)
    var s = ""
    fmt.Scanf("%s", &s)
    return s

}

func inputInt(prompt string) int {

    var number int64
    var err error
    for {
        number, err = strconv.ParseInt(inputString(prompt), 10, 0)
        if err == nil {
            break
        } else {
            fmt.Println("Integer expected.")
        }
    }
    return int(number)

}

func main() {

    var s = inputString("Enter a string: ")
    var n = inputInt("Enter an integer: ")

    fmt.Println()

    fmt.Printf("ASC(\"%s\") --> ", s)
    fmt.Printf("int([]rune(\"%s\")[0]) --> %v\n", s, int([]rune(s)[0]))

    fmt.Printf("CHR$(%v) --> ", n)
    fmt.Printf("rune(%v) --> '%v'\n", n, rune(n))

    fmt.Printf("LEFT$(\"%s\", %v) --> ", s, n)
    //fmt.Printf("\"%s\"[:%v] --> \"%s\"\n", s, n, s[:n]) // byte slices, ASCII only
    fmt.Printf("string([]rune(\"%s\")[:%v])) --> \"%s\"\n", s, n, string([]rune(s)[:n]))

    fmt.Printf("MID$(\"%s\", %v) --> ", s, n)
    // XXX FIXME When n is greater than string length, the result is not that of the BASIC original:
    // fmt.Printf("\"%s\"[%v-1:] --> \"%s\"\n", s, n, s[n-1:]) // byte slices, ASCII only
    fmt.Printf("string([]rune(\"%s\")[%v-1:])) --> \"%s\"\n", s, n, string([]rune(s)[n-1:]))

    fmt.Printf("MID$(\"%s\", %v, 3) --> ", s, n)
    // fmt.Printf("\"%s\"[%v-1:%v-1+3] --> \"%s\"\n", s, n, n, s[n-1:n-1+3]) // byte slices, ASCII only
    fmt.Printf("string([]rune(\"%s\")[%v-1:%v-1+3])) --> \"%s\"\n", s, n, n, string([]rune(s)[n-1:n-1+3]))

    fmt.Printf("RIGHT$(\"%s\", %v) --> ", s, n)
    // fmt.Printf("\"%s\"[len(\"%s\")-%v:] --> \"%s\"\n", s, s, n, s[len(s)-n:]) // byte slices, ASCII only
    fmt.Printf("string([]rune(\"%s\")[len([]rune(\"%s\"))-%v:])) --> \"%s\"\n", s, s, n, string([]rune(s)[len([]rune(s))-n:]))

    fmt.Printf("LEN(\"%s\") --> ", s)
    //fmt.Printf("len(\"%s\") --> %v\n", s, len(s)) // byte slices, ASCII only
    fmt.Printf("len([]rune(\"%s\")) --> %v\n", s, len([]rune(s))) // byte slices, ASCII only

    fmt.Printf("VAL(\"%s\") --> ", s)
    var val, _ = strconv.ParseInt(s, 10, 0)
    fmt.Printf("var val, err = strconv.ParseInt(\"%s\", 10, 0) /* result in `val`, error in `err` */ --> %v\n", s, val)

    fmt.Printf("STR$(%v) --> ", n)
    fmt.Printf("fmt.Sprint(%v) --> \"%s\"\n", n, fmt.Sprint(n))

    fmt.Printf("SPC(%v) --> ", n)
    fmt.Printf("strings.Repeat(\" \", %v) --> \"%s\"\n", n, strings.Repeat(" ", n))

}

En Hare

// Strings
//
// Original version in BASIC:
//      Example included in Vintage BASIC 1.0.3.
//      http://www.vintage-basic.net
//
// This version in Hare:
//      Copyright (c) 2025, Marcos Cruz (programandala.net)
//      SPDX-License-Identifier: Fair
//
// Written in 2025-02-14/15.
//
// Last modified: 20260213T1645+0100.

// Modules {{{1
// =============================================================================

use bufio;
use fmt;
use os;
use strconv;
use strings;

// User input {{{1
// =============================================================================

fn print_prompt(prompt: str) void = {
        fmt::print(prompt)!;
        bufio::flush(os::stdout)!;
};

fn accept_string(prompt: str = "") str = {
        print_prompt(prompt);
        const buffer = match (bufio::read_line(os::stdin)!) {
                case let buffer: []u8 =>
                        yield buffer;
                case =>
                        return "";
                };
        defer free(buffer);
        return strings::dup(strings::fromutf8(buffer)!)!;
};

fn accept_integer() (int | ...strconv::error) = {
        const s = accept_string();
        defer free(s);
        return strconv::stoi(s);
};

fn prompted_integer(prompt: str) (int | ...strconv::error) = {
        fmt::print(prompt)!;
        bufio::flush(os::stdout)!;
        return accept_integer();
};

fn prompted_valid_integer(prompt: str, error: str = "Integer expected.") int = {
        let result: int = 0;
        for (true) {
                match (prompted_integer(prompt)) {
                case let i: int =>
                        result = i;
                        break;
                case =>
                        fmt::println(error)!;
                };
        };
        return result;
};

// Main {{{1
// =============================================================================

fn repeat(s: str, n: int) str = {
        let result = "";
        for (let i: int = 0; i < n; i += 1) {
                result = strings::concat(result, s)!;
        };
        return result;
};

export fn main() void = {
        let s = accept_string("Enter a string: ");
        defer free(s);
        let n = prompted_valid_integer("Enter an integer: ");

        fmt::println()!;

        fmt::printf("ASC(\"{}\") --> ", s)!;
        fmt::printf("strings::toutf8(\"{}\"[0]): int --> ", s)!;
        fmt::printfln("{}", strings::toutf8(s)[0]: int)!;

        fmt::printf("CHR$({}) --> ", n)!;
        fmt::printfln("{}: rune --> '{}'", n, n: rune)!;

        // XXX FIXME When `n` is greater than the string length, the behaviour
        // is different from the original `LEFT$`, `MID$` and `RIGHT$`.

        fmt::printf("LEFT$(\"{}\", {}) --> ", s, n)!;
        fmt::printf("strings::sub(\"{}\", 0, {}: size) --> ", s, n)!;
        fmt::printfln("\"{}\"", strings::sub(s, 0, n: size))!;

        fmt::printf("MID$(\"{}\", {}) --> ", s, n)!;
        fmt::printf("strings::sub(\"{0}\", ({1} - 1): size, len(\"{0}\")) --> ", s, n)!;
        fmt::printfln("\"{}\"", strings::sub(s, (n - 1): size, len(s)))!;

        fmt::printf("MID$(\"{}\", {}, 3) --> ", s, n)!;
        fmt::printf("strings::sub(\"{0}\", ({1} - 1): size, ({1} - 1 + 3): size) --> ", s, n)!;
        fmt::printfln("\"{}\"", strings::sub(s, (n - 1): size, (n - 1 + 3): size))!;

        fmt::printf("RIGHT$(\"{}\", {}) --> ", s, n)!;
        fmt::printf("strings::sub(\"{0}\", len(\"{0}\") - {1}: size, len(\"{0}\")) --> ", s, n)!;
        fmt::printfln("\"{}\"", strings::sub(s, len(s) - n: size, len(s)))!;

        fmt::printf("LEN(\"{}\") --> ", s)!;
        fmt::printfln("len(\"{}\") --> {}", s, len(s))!;

        fmt::printf("VAL(\"{}\") --> ", s)!;
        fmt::printf("match (strconv::stof64(\"{}\")) {{ case let i: int => yield i; case => yield 0; }}", s)!;
        fmt::printfln(" --> {}",
                match (strconv::stof64(s)) {
                case let i: f64 =>
                        yield i;
                case =>
                        yield 0;
                }
        )!;

        fmt::printf("STR$({}) --> ", n)!;
        fmt::printfln("fmt::asprint({}) --> \"{}\"", n, fmt::asprint(n)!)!;

        fmt::printf("SPC({}) --> ", n)!;
        fmt::printfln("repeat(\" \", {}) --> \"{}\"", n, repeat(" ", n))!;
        fmt::printf("NB: `repeat` is an ad hoc function.")!;
};

En Janet

# Strings

# Original version in BASIC:
#  Example included in Vintage BASIC 1.0.3.
#  http://www.vintage-basic.net

# This version in Janet:
#  Copyright (c) 2025, Marcos Cruz (programandala.net)
#  SPDX-License-Identifier: Fair
#
# Written on 2025-12-24.
#
# Last modified 20251225T1946+0100.

(defn accept-string [prompt-text]
  (prin prompt-text)
  (string/trim (getline)))

(defn accept-integer [prompt-text-text]
  (def input (accept-string prompt-text-text))
  (def number (scan-number input))
  (if number
    (math/trunc number)
    (do
      (print "Number expected.")
      (accept-integer prompt-text-text))))

(defn main [& args]
  (def s (accept-string "Enter a string: "))
  (def n (accept-integer "Enter a number: "))
  (print
    (string/format
      "ASC(\"%s\") --> (get (string/bytes \"%s\") 0) --> %d"
      s s (get (string/bytes s) 0)))
  (print
    (string/format
      "CHR$(%d) --> (string/from-bytes %d) --> \"%s\""
      n n (string/from-bytes n)))
  (print
    (string/format
      "LEFT$(\"%s\", %d) --> (string/slice \"%s\" 0 (min %d (length \"%s\"))) --> \"%s\""
      s n s n s (string/slice s 0 (min n (length s)))))
  (print
    (string/format
      "MID$(\"%s\", %d) --> (string/slice \"%s\" (min (- %d 1) (length \"%s\"))) --> \"%s\""
      s n s n s (string/slice s (min (- n 1) (length s)))))
  (print
    (string/format
      "MID$(\"%s\", %d, 3) --> (string/slice \"%s\" (min (- %d 1) (length \"%s\")) (min (+ (- %d 1 ) 3) (length \"%s\"))) --> \"%s\""
      s n s n s n s (string/slice s (min (- n 1) (length s)) (min (+ (- n 1) 3) (length s)))))
  (print
    (string/format
      "RIGHT$(\"%s\", %d) --> (string/slice \"%s\" (max (- (+ 1 (length \"%s\"))) (- (+ 1 %d)))) --> \"%s\""
      s n s s n (string/slice s (max (- (+ 1 (length s))) (- (+ 1 n))))))
  (print
    (string/format
      "LEN(\"%s\") --> (length \"%s\") --> %d"
      s s (length s)))
  (print
    (string/format
      "VAL(\"%s\") --> (or (scan-number \"%s\") 0) --> %d"
      s s (or (scan-number s) 0)))
  (print
    (string/format
      "STR$(%d) --> (string %d) --> \"%s\""
      n n (string n)))
  (print
    (string/format
      "SPC(%d) --> (string/repeat \" \" %d) --> \"%s\""
      n n (string/repeat " " n))))

En Julia

# Strings

# Original version in BASIC:
#     Example included in Vintage BASIC 1.0.3.
#     http://www.vintage-basic.net

# This version in Julia:
#     Copyright (c) 2023, Marcos Cruz (programandala.net)
#     SPDX-License-Identifier: Fair

# Written in 2023-07, 2023-09.

# Last modified: 20240704T1050+0200.

using Unicode

print("Enter a string: ")
s = readline()

n = 0

while true
    print("Enter a whole number: ")
    f = tryparse(Float64, readline())
    if f != nothing
        global n = convert(Int64, floor(f))
        if n == f
            break
        end
    end
    println("Not a valid whole number.")
end

print("ASC(\"$s\") --> ")
print("convert(Int, convert(Char, \"$s\"[1])) --> ")
println(convert(Int, s[1]))

print("CHR\$($n) --> ")
print("convert(Char, $n) --> ")
println("'", convert(Char, n), "'")

print("LEFT\$(\"$s\", $n) --> ")
print("graphemes(\"$s\", 1 : min($n, length(\"$s\"))) --> ")
println("\"", graphemes(s, 1 : min(n, length(s))), "\"")

print("MID\$(\"$s\", $n) --> ")
print("graphemes(\"$s\", $n : length(\"$s\") --> ")
println("\"", graphemes(s, n : length(s)), "\"")

print("MID\$(\"$s\", $n, 3) --> ")
print("graphemes(\"$s\", $n : min($n + 3 - 1, length(\"$s\")) --> ")
println("\"", graphemes(s, n : min(n + 3 - 1, length(s))), "\"")

print("RIGHT\$(\"$s\", $n) --> ")
print("graphemes(\"$s\", max(length(\"$s\") - $n + 1, 1) : length(\"$s\") --> ")
println("\"", graphemes(s, max(length(s) - n + 1, 1) : length(s)), "\"")

print("LEN(\"$s\") --> ")
print("length(\"$s\") --> ")
println(length(s))

print("VAL(\"$s\") --> ")
print("tryparse(Float64, \"$s\") == nothing ? 0 : parse(Float64, \$$s\$) --> ")
println(tryparse(Float64, s) == nothing ? 0 : parse(Float64, s))

print("STR\$($n) --> ")
print("string($n) --> ")
println("\"", string(n), "\"")

print("SPC($n) --> ")
print("repeat(\" \", $n) --> ")
println("\"", repeat(" ", n), "\"")

En Kotlin

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Kotlin:
    Copyright (c) 2023, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2023-09, 2023-10.

Last modified: 20260205T1349+0100.
*/

fun main() {

    print("Enter a string: ")
    val s = readln()
    print("Enter a number: ")
    val input = readln()
    val n = input.toInt()

    print("$s and $n\n")

    print("ASC(\"$s\") --> ")
    print("\"$s\"[0].code --> ")
    println("${s[0].code}")

    print("CHR$($n) --> ")
    print("$n.toChar() --> ")
    println("'${n.toChar()}'")

    print("LEFT$(\"$s\", $n) --> ")
    print("\"$s\".substring(0, minOf(\"$s\".length $n)) --> ")
    println(s.substring(0, minOf(s.length, n)))

    print("MID$(\"$s\", $n) --> ")
    print("\"$s\".substring(minOf(\"$s\".length, $n - 1)) --> ")
    println(s.substring(minOf(s.length, n - 1)))

    print("MID$(\"$s\", $n, 3) --> ")
    print("\"$s\".substring(minOf(\"$s\".length, $n - 1), minOf(\"$s\".length, $n - 1 + 3)) --> ")
    println(s.substring(minOf(s.length, n - 1), minOf(s.length, n - 1 + 3)))

    print("RIGHT$(\"$s\", $n) --> ")
    print("\"$s\".substring(maxOf(0, \"$s\".length - $n)) --> ")
    println(s.substring(maxOf(0, s.length - n)))

    print("LEN(\"$s\") --> ")
    print("\"$s\".lenght --> ")
    println(s.length)

    print("VAL(\"$s\") --> ")
    print("\"$s\".toFloat() --> ")
    println("${try { s.toFloat() } catch(e: Exception){ 0.0 }}")

    print("STR$($n) --> ")
    print("$n.toString() --> ")
    println("\"${n.toString()}\"")

    print("SPC($n) --> ")
    print("\" \".repeat($n) --> ")
    println("\"${" ".repeat(n)}\"")

}

En Nim

#[
Strings

Original version in BASIC:
  Example included in Vintage BASIC 1.0.3.
  http://www.vintage-basic.net

This version in Nim:
  Copyright (c) 2023, 2025, Marcos Cruz (programandala.net)
  SPDX-License-Identifier: Fair

Written on 2023-08-27, 2025-01-20.

Last modified: 20250405T0304+0200.
]#

import std/strutils

write(stdout, "Enter a string: ")
let s = readLine(stdin)

var n: int
while true:
  try:
    write(stdout, "Enter a number: ")
    n = parseInt(readLine(stdin))
    break
  except ValueError:
    writeLine(stdout, "Integer expected.")

echo ""

echo "ASC(\"", s, "\") --> int(char(", s, "[0])) --> ", int(char(s[0]))
echo "CHR$(", n, ") --> char(", n, ") --> '", char(n), "'"
echo "LEFT$(\"", s, "\", ", n, ") --> \"", s, "\"[0 ..< ", n, "] --> ", s[0 ..< n]
echo "MID$(\"", s, "\", ", n, ") --> \"", s, "\"[", n, "-1 .. ^1] --> ", s[n-1 .. ^1]
echo "MID$(\"", s, "\", ", n, ", 3) --> \"", s, "\"[", n, "-1 ..< ", n, "+3-1] --> ", s[n-1 ..< n+3-1]
echo "RIGHT$(\"", s, "\", ", n, ") --> \"", s, "\"[^", n, " .. ^1] --> ", s[^n .. ^1]
echo "LEN(\"", s, "\") --> \"", s, "\".len --> ",s.len
echo "VAL(\"", s, "\") --> (try: parseInt(\"", s, "\") except: 0) --> ", (try: parseInt(s) except: 0)
echo "STR$(", n, ") --> $", n, " --> \"", $n, "\""
echo "SPC(", n, ") --> strutils.repeat(' ', ", n, ") --> \"", strutils.repeat(' ',n), "\""

En Odin

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Odin:
    Copyright (c) 2023, 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2023-04, 2023-09, 2023-12, 2025-04.

Last modified: 20250424T1230+0200.
*/

package vintage_basic_strings

import "../lib/anodino/src/read"
import "core:fmt"
import "core:strconv"
import "core:strings"
import "core:unicode/utf8"

get_string :: proc(prompt : string) -> string {
    fmt.print(prompt)
    return read.a_string() or_else ""
}

get_number :: proc(prompt : string) -> (number : int) {
    ok := false
    for ; !ok; number, ok = strconv.parse_int(get_string(prompt)) {}
    return
}

main :: proc() {

    s := get_string("Enter a string: ")
    n := get_number("Enter an integer: ")

    fmt.println()

    fmt.printf("ASC(\"%s\") --> ", s)
    fmt.printfln("int(utf8.string_to_runes(\"%s\")[0]) --> %v", s, int(utf8.string_to_runes(s)[0]))

    fmt.printf("CHR$(%v) --> ", n)
    fmt.printfln("rune(%v) --> '%v'", n, rune(n))

    fmt.printf("LEFT$(\"%s\", %v) --> ", s, n)
    fmt.printfln("strings.cut(\"%s\", %v, %v) --> \"%s\"", s, 0, n, strings.cut(s, 0, n))

    fmt.printf("MID$(\"%s\", %v) --> ", s, n)
    // XXX FIXME When n is greater than string length, the result is not that of the BASIC original:
    fmt.printfln("strings.cut(\"%[0]s\", %[1]v - 1, len(\"%[0]s\") - %[1]v - 1) --> \"%[2]s\"", s, n, strings.cut(s, n - 1, len(s) - 1))

    fmt.printf("MID$(\"%s\", %v, 3) --> ", s, n)
    fmt.printfln("strings.cut(\"%s\", %v - 1, 3) --> \"%s\"", s, n, strings.cut(s, n - 1, 3))

    fmt.printf("RIGHT$(\"%s\", %v) --> ", s, n)
    fmt.printfln("strings.cut(\"%[0]s\", len(\"%[0]s\")-%[1]v, %[1]v) --> \"%[2]s\"", s, n, strings.cut(s, len(s) - n, n))

    fmt.printf("LEN(\"%s\") --> ", s)
    fmt.printfln("len(\"%s\") --> %v", s, len(s))

    fmt.printf("VAL(\"%s\") --> ", s)
    fmt.printfln("strconv.parse_int(\"%s\") or_else 0 --> %v", s, strconv.parse_int(s) or_else 0)

    fmt.printf("STR$(%v) --> ", n)
    fmt.printfln("fmt.tprint(%v) --> \"%s\"", n, fmt.tprint(n))

    fmt.printf("SPC(%v) --> ", n)
    fmt.printfln("strings.repeat(\" \", %v) --> \"%s\"", n, strings.repeat(" ", n))

}

En Pike

#! /usr/bin/env pike

// Strings

// Original version in BASIC:
//  Example included in Vintage BASIC 1.0.3.
//  http://www.vintage-basic.net

// This version in Pike:
//  Copyright (c) 2025, Marcos Cruz (programandala.net)
//  SPDX-License-Identifier: Fair
//
// Written on 2025-03-10, 2025-03-12.
//
// Last modified: 20250312T1809+0100.

string accept_string(string prompt) {
    write(prompt);
    return Stdio.stdin->gets();
}

int accept_integer(string prompt) {
    // NB The casting accepts any valid integer at the start of the string
    // and ignores the rest;  if no valid integer is found at the start of
    // the string, zero is returned.
    return (int) accept_string(prompt);
}

int accept_valid_integer(string prompt) {
    int n = 0;
    while (n <= 0) {
        n = accept_integer(prompt);
        if (n <= 0) {
            write("Integer greater than zero expected.\n");
        }
    }
    return n;
}

void main() {

    string s = accept_string("Enter a string: ");
    int n = accept_valid_integer("Enter an integer: ");

    write("ASC(\"%[0]s\") --> (int) \"%[0]s\"[0] --> %[1]d\n", s, (int) s[0]);
    write("CHR$(%[0]d) --> sprintf(\"%%c\", %[0]d) --> \"%[1]s\"\n", n, sprintf("%c", n));
    write("LEFT$(\"%[0]s\", %[1]d) --> \"%[0]s\"[..%[1]d - 1] --> \"%[2]s\"\n", s, n, s[..n - 1]);
    write("MID$(\"%[0]s\", %[1]d) --> \"%[0]s\"[%[1]d - 1..] --> \"%[2]s\"\n", s, n, s[n - 1..]);
    write("MID$(\"%[0]s\", %[1]d, 3) --> \"%[0]s\"[%[1]d - 1 .. %[1]d - 1 + 3 - 1] --> \"%[2]s\"\n", s, n, s[n - 1 .. n - 1 + 3 - 1]);
    write("RIGHT$(\"%[0]s\", %[1]d) --> \"%[0]s\"[sizeof(%[0]s) - %[1]d..] --> \"%[2]s\"\n", s, n, s[sizeof(s) - n..]);
    write("LEN(\"%[0]s\") --> sizeof(\"%[0]s\") --> %[1]d\n", s, sizeof(s));
    write("VAL(\"%[0]s\") --> (float) \"%[0]s\" --> %[1]f\n", s, (float) s);
    write("STR$(%[0]d) --> (string) %[0]d --> \"%[1]s\"\n", n, (string) n);
    write("SPC(%[0]d) --> \" \" * %[0]d -> \"%[1]s\"\n", n, " " * n);

}

En Python

# Strings

# Original version in BASIC:
#     Example included in Vintage BASIC 1.0.3.
#     http://www.vintage-basic.net

# This version in Python:
#     Copyright (c) 2024, Marcos Cruz (programandala.net)
#     SPDX-License-Identifier: Fair
#
# Written on 2024-10-29.
#
# Last modified: 20241203T2231+0100.

import ast

s = input("Enter a string: ")

while True:
    try:
        n = int(ast.literal_eval(input("Enter a number: ")))
        break
    except:
        print("Not a valid number.")

print(f"ASC(\"{s}\"[0]) --> ", end = "")
print(f"ord(\"{s}\"[0])) --> ", end = "")
print(ord(s[0]))

print(f"CHR$({n}) --> ", end = "")
print(f"chr({n}) --> ", end = "")
print('"', chr(n), '"', sep = "")

print(f"LEFT$(\"{s}\", {n}) --> ", end = "")
print(f"\"{s}\"[:{n}] --> ", end = "")
print("\"", s[:n], "\"", sep = "")

print(f"MID$(\"{s}\", {n}) --> ", end = "")
print(f"\"{s}\"[{n} : len(\"{s}\")] --> ", end = "")
print("\"", s[n : len(s)], "\"", sep = "")

print(f"MID$(\"{s}\", {n}, 3) --> ", end = "")
print(f"\"{s}\"[{n} : min({n} + 3, len(\"{s}\"))] --> ", end = "")
print("\"", s[n : min(n + 3, len(s))], "\"", sep = "")

print(f"RIGHT$(\"{s}\", {n}) --> ", end = "")
print(f"(\"{s}\", max(len(\"{s}\") - {n}, 1) : length(\"{s}\") --> ", end = "")
print("\"", s[max(len(s) - n, 0) : len(s)], "\"", sep = "")

print(f"LEN(\"{s}\") --> ", end = "")
print(f"len(\"{s}\") --> ", end = "")
print(len(s))

# XXX TODO return 0 is the string is not a valid number
print(f"VAL(\"{s}\") --> ", end = "")
print(f"int(\"{s}\") --> ", end = "")
print(int(s))

print(f"STR$({n}) --> ", end = "")
print(f"str({n}) --> ", end = "")
print("\"", str(n), "\"", sep = "")

print(f"SPC({n}) --> ", end = "")
print(f"\" \" * {n} --> ", end = "")
print("\"", " " * n, "\"", sep = "")

En Raku

# Strings
#
# Original version in BASIC:
#   Example included in Vintage BASIC 1.0.3.
#   http://www.vintage-basic.net
#
# This version in Raku:
#   Copyright (c) 2024, 2025, Marcos Cruz (programandala.net)
#   SPDX-License-Identifier: Fair
#
# Written in 2024-12.
#
# Last modified: 20250731T1726+0200.

sub prompt_number(Str $prompt --> Int) {

    my Int $n;

    loop {
        try {
            $n = +prompt $prompt;
            CATCH {
                default {
                    put 'Integer expected.';
                    next;
                }
            }
        }
        last;
    }
    return floor $n;

}

my $s = prompt 'Enter a string: ';
my $n = prompt_number 'Enter an integer: ';

put "";

put "ASC(\"$s\") --> ord(\"$s\") --> $(ord($s))";
put "CHR\$($n) --> $n.chr --> \"", $n.chr, '"';
put "LEFT\$(\"$s\", $n) --> \"$s\".comb.head($n).join --> '", $s.comb.head($n).join, "'";

put "MID\$(\"$s\", $n) --> \"$s\".comb[$n - 1 .. *].join --> '", $s.comb[$n - 1 .. *].join, "'";
put "MID\$(\"$s\", $n, 3) --> \"$s\".comb[$n - 1 .. $n -1 + 3 - 1].join --> '", $s.comb[$n - 1 .. $n - 1 + 3 - 1].join, "'";

put "RIGHT\$(\"$s\", $n) --> \"$s\".comb.tail($n).join --> '", $s.comb.tail($n).join, "'";

put "LEN(\"$s\") --> \"$s\".chars --> ", $s.chars;

put "VAL(\"$s\") --> val(\"$s\") --> ", val($s);

sub val_or_0(Str $s) {
    my Any $n;
    try { $n = +$s; CATCH { default { $n = 0 } } }
    return $n
}

put "VAL(\"$s\") --> val_or_0(\"$s\") --> ", val_or_0($s), " # custom subroutine with `try`";

put "STR$($n) --> $n.Str --> \"", $n.Str, '"';

put "SPC($n) --> ' ' x $n --> '", ' ' x $n, "'";

En Ring

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Ring:
    Copyright (c) 2024, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written in 2024-03, 2024-04.

Last modified: 20240411T0954+0200.
*/

// Print the given prompt, get an integer from the user, check it and return it.
func validInteger(prompt)
    while true
        put prompt
        get n
        if isDigit(n)
            break
        else
            put "Integer number expected. Retry." + nl
        end
    end
    return 0 + n
end

func main() {

    print("Enter a string: ")
    s = getString()
    n = validInteger("Enter a number: ")

    print(`ASC("#{s}") --> `)
    print(`ascii(left("#{s}", 1)) --> `)
    ? ascii(left(s, 1))

    print(`CHR$(#{n}) --> `)
    print(`char(#{n}) --> `)
    ? char(n)

    print(`LEFT$("#{s}", #{n}) --> `)
    print(`left("#{s}", n) --> `)
    ? left(s,n)

    print(`MID$("#{s}", #{n}) --> `)
    print(`substr("#{s}", #{n}) --> `)
    ? substr(s, n)

    print(`MID$("#{s}", #{n}, 3) --> `)
    print(`substr("#{s}", #{n}, 3) --> `)
    ? substr(s, n, 3)

    print(`RIGHT$("#{s}", #{n}) --> `)
    print(`right("#{s}", n) --> `)
    ? right(s,n)

    print(`LEN("#{s}") --> `)
    print(`len("#{s}") --> `)
    ? len(s)

    print(`VAL("#{s}") --> `)
    print(`number("#{s}") --> `)
    ? number(s)
    print(`VAL("#{s}") --> `)
    print(`0 + "#{s}" --> `)
    ? 0 + s

    print(`STR$(#{n}) --> `)
    print(`string(#{n}) --> `)
    ? string(n)

    print(`SPC(#{n}) --> `)
    print(`copy(" ", #{n}) --> `)
    ? `"` + copy(" ", n) + `"`

}

En Scala

// Strings
//
// Original version in BASIC:
//   Example included in Vintage BASIC 1.0.3.
//   http://www.vintage-basic.net
//
// This version in Scala:
//   Copyright (c) 2023, Marcos Cruz (programandala.net)
//   SPDX-License-Identifier: Fair
//
// Written in 2023-09-28/29.
//
// Last modified: 20231209T2008+0100.

// Prompts the user to enter a command and returns it trimmed.
def readString(prompt : String = "") : String =
  scala.io.StdIn.readLine(prompt).trim

// Prompts the user to enter an integer and returns it.
def readInteger(prompt : String = "") : Int =
  var integer = 0
  var ok = false
  while !ok do
    try
      integer = readString(prompt).toInt
      ok = true
    catch
    case _ => println("That wasn't a valid integer.")
  integer

@main def main() =

  val s = readString("Enter a string: ")
  val n = readInteger("Enter an integer: ")

  print(s"ASC(\"$s\") --> ")
  print(s"\"$s\"(0).toChar.toInt --> ")
  println(s"${s(0).toChar.toInt}")

  print(s"CHR$$($n) --> ")
  print(s"$n.toChar --> ")
  println(s"'${n.toChar}'")

  print(s"LEFT$$(\"$s\", $n) --> ")
  print(s"\"$s\".substring(0, $n.min(\"$s\".size)) --> ")
  println(s"\"${s.substring(0, n.min(s.size))}\"")

  print(s"MID$$(\"$s\", $n) --> ")
  print(s"\"$s\".substring(($n - 1).min(\"$s\".size)) --> ")
  println(s"\"${s.substring((n - 1).min(s.size))}\"")

  print(s"MID$$(\"$s\", $n, 3) --> ")
  print(s"\"$s\".substring(($n - 1).min(\"$s\".size), ($n - 1 + 3).min(\"$s\".size)) --> ")
  println(s"\"${s.substring((n - 1).min(s.size), (n - 1 + 3).min(s.size))}\"")

  print(s"RIGHT$$(\"$s\", $n) --> ")
  print(s"\"$s\".substring((\"$s\".size - $n).max(0)) --> ")
  println(s"\"${s.substring((s.size - n).max(0))}\"")

  print(s"LEN(\"$s\") --> ")
  print(s"\"$s\".size --> ")
  println(s.size)

  print(s"VAL(\"$s\") --> ")
  print(s"try \"$s\".trim.toFloat catch case _ => (0.0) --> ")
  println(try s.trim.toFloat catch case _ => (0.0))

  print(s"STR$$($n) --> ")
  print(s"$n.toString --> ")
  println(s"\"${n.toString}\"")

  print(s"SPC($n) --> ")
  print(s"\" \".repeat($n) --> ")
  println(s"\"${" ".repeat(n)}\"")

En Scheme

; Strings

; Original version in BASIC:
;   Example included in Vintage BASIC 1.0.3.
;   http://www.vintage-basic.net

; This version in Scheme (Bigloo):
;   Copyright (c) 2025, Marcos Cruz (programandala.net)
;   SPDX-License-Identifier: Fair
;
; Written on 2025-12-05.
;
; Last modified 20251224T1216+0100.

(module strings)

(define (accept-string prompt)
    (display prompt)
    (read-line))

(define (accept-integer prompt)
    (let ((input (accept-string prompt)))
        (let ((number (string->number input)))
            (if number
                (truncate number)
                (begin
                    (display "Number expected.")
                    (newline)
                    (accept-integer prompt))))))

(define s (accept-string "Enter a string: "))
(define n (accept-integer "Enter a number: "))

(display
    (format
        "ASC(\"~s\") --> (char->integer (car (string->list \"~s\"))) --> ~d\n"
        s s (char->integer (car (string->list s)))))

(display
    (format
        "CHR$(~d) --> (integer->char ~d) --> \"~s\"\n"
        n n (integer->char n)))

(display
    (format
        "LEFT$(\"~s\", ~d) --> (substring \"~s\" 0 ~d) --> \"~s\"\n"
        s n s n (substring s 0 n)))

(display
    (format
        "MID$(\"~s\", ~d) --> (substring \"~s\" (- ~d 1)) --> \"~s\"\n"
        s n s n (substring s (- n 1))))

(display
    (format
        "MID$(\"~s\", ~d, 3) --> (substring \"~s\" (- ~d 1) (+ (- ~d 1 ) 3)) --> \"~s\"\n"
        s n s n  n (substring s (- n 1) (+ (- n 1) 3))))

(display
    (format
        "RIGHT$(\"~s\", ~d) --> (substring \"~s\" (- (string-length \"~s\") ~d)) --> \"~s\"\n"
        s n s s n (substring s (- (string-length s) n))))

(display
    (format
        "LEN(\"~s\") --> (string-length \"~s\") --> ~d\n"
        s s (string-length s)))

(display
    (format
        "VAL(\"~s\") --> (or (string->number \"~s\") 0) --> ~d\n"
        s s (or (string->number s) 0)))

(display
    (format
        "STR$(~d) --> (number->string ~d) --> \"~s\"\n"
        n n (number->string n)))

(display
    (format
        "SPC(~d) --> (make-string ~d #\\space) --> \"~s\"\n"
        n n (make-string n #\space)))

En Swift

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in Swift:
    Copyright (c) 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2025-04-24.

Last modified: 20250424T1551+0200.
*/

func promptedString(with prompt: String) -> String {
    while true {
        print(prompt, terminator: "")
        if let input = readLine() {
            return input
        }
    }
}

func promptedInteger(with prompt: String) -> Int {
    while true {
        print(prompt, terminator: "")
        if let input = readLine(), let number = Int(input) {
            return number
        } else {
            print("Integer expected.")
        }
    }
}

var s = promptedString(with: "Enter a string: ")
var n = promptedInteger(with: "Enter an integer: ")

var start: String.Index
var end: String.Index
var result: String.SubSequence

print()

print("ASC(\"\(s)\") --> ", terminator: "")
print("\"s\".unicodeScalars.map { $0.value } [0] --> \(s.unicodeScalars.map { $0.value } [0])")

print("CHR$(\(n)) --> ", terminator: "")
print("Character(UnicodeScalar(\(n))!) --> \"\(Character(UnicodeScalar(n)!))\"")

// XXX TODO check limits of substrings in order to mimic the behaviour of the
// original BASIC functions

print("LEFT$(\"\(s)\", \(n)) -->")
print("""
            let s: \"\(s)\"
            let n: \(n)
            let end: String.Index = s.index(s.startIndex, offsetBy: n)
            let result: StringSubSequence = s[..<end]
        """)
end = s.index(s.startIndex, offsetBy: n)
result = s[..<end]
print("--> \"\(result)\"")

print("MID$(\"\(s)\", \(n)) -->")
print("""
            let s: \"\(s)\"
            let n: \(n)
            let start: String.Index = s.index(s.startIndex, offsetBy: n - 1)
            let result: String.SubSequence = s[start...]
        """)
start = s.index(s.startIndex, offsetBy: n - 1)
result = s[start...]
print("--> \"\(result)\"")

print("MID$(\"\(s)\", \(n), 3) -->")
print("""
            let s: \"\(s)\"
            let n: \(n)
            let start: String.Index = s.index(s.startIndex, offsetBy: n - 1)
            let end: String.Index = s.index(start, offsetBy: 3)
            let result String.SubSequence = s[start..<end]
        """)
start = s.index(s.startIndex, offsetBy: n - 1)
end = s.index(start, offsetBy: 3)
result = s[start..<end]
print("--> \"\(result)\"")

print("RIGHT$(\"\(s)\", \(n)) --> ")
print("""
            let s: \"\(s)\"
            let n: \(n)
            let start: String.Index = s.index(s.endIndex, offsetBy: -n)
            let result: String.SubSequence = s[start...]
        """)
start = s.index(s.endIndex, offsetBy: -n)
result = s[start...]
print("--> \"\(result)\"")

print("LEN(\"\(s)\") --> ", terminator: "")
print("\"\(s)\".count --> \(s.count)")

print("VAL(\"\(s)\") --> ", terminator: "")
print("Double(\"\(s)\") ??  0 --> \(Double(s) ?? 0)")

print("STR$(\(n)) --> ", terminator: "")
print("String(\(n)) --> \"\(String(n))\"")

print("SPC(\(n)) --> ", terminator: "")
print("String(repeating: \" \", count: \(n)) --> \"\(String(repeating: " ", count: n))\"")

En V

/*
Strings

Original version in BASIC:
    Example included in Vintage BASIC 1.0.3.
    http://www.vintage-basic.net

This version in V:
    Copyright (c) 2025, Marcos Cruz (programandala.net)
    SPDX-License-Identifier: Fair

Written on 2025-01-03/04.

Last modified: 20250714T1332+0200.
*/
import encoding.utf8
import math
import os
import strconv
import strings

fn input_int(prompt string) int {
    mut n := 0
    for {
        n = strconv.atoi(os.input(prompt)) or { continue }
        break
    }
    return n
}

fn main() {
    s := os.input('Enter a string: ')
    n := input_int('Enter an integer: ')

    println('')

    print("ASC('${s}') --> ")
    println("int(utf8.get_rune('${s}', 0))) --> ${int(utf8.get_rune(s, 0))}")

    print('CHR$(${n}) --> ')
    println("rune(${n}) --> '${rune(n)}'")

    print("LEFT$('${s}', ${n}) --> ")
    println("'${s}'.runes()[0..math.min(${n}, '${s}'.len)].string() --> '${s.runes()[0..math.min(n,
        s.len)].string()}'")

    // XXX FIXME the program fails when n is out of bounds; BASIC returns an empty string instead
    print("MID$('${s}', ${n}) --> ")
    println("'${s}'.runes()[${n}-1..].string() --> '${s.runes()[n - 1..].string()}'")

    // XXX FIXME the program fails when n is out of bounds; BASIC returns an empty string instead
    print("MID$('${s}', ${n}, 3) --> ")
    println("'${s}'.runes()[${n}-1..${n}-1+3].string() --> '${s.runes()[n - 1..n - 1 + 3].string()}'")

    print("RIGHT$('${s}', ${n}) --> ")
    println("'${s}'.runes()#[-${n}..].string() --> '${s.runes()#[-n..].string()}'")

    print("LEN('${s}') --> ")
    println("'${s}'.len --> ${s.len}")

    print("VAL('${s}') --> ")
    println("strconv.atoi('${s}') or { 0 } --> ${strconv.atoi(s) or { 0 }}")

    print('STR$(${n}) --> ')
    println("${n}.str() --> '${n.str()}'")

    print('SPC(${n}) --> ')
    println("strings.repeat(` `, ${n}) --> '${strings.repeat(` `, n)}'")
}

Rilataj paĝoj

Basics off
Metaprojekto pri la projektoj «Basics of…».

Eksteraj rilataj ligiloj