TypeShell
TypeShell is a Go-like programming language that transpiles down to Batch or Bash.
rem Transpile helloworld.tsh to Batch and Bash and write the scripts to the current directory.
tsh.exe -i helloworld.tsh -t batch -t bash -o .
Example
// helloworld.tsh
func hello() string {
return "hello"
}
func buildGreeting(p string) string {
return hello() + " " + p
}
greeting := buildGreeting("world")
print(greeting) // Prints "Hello World" to the console.
Basics
Variables
Supported variable types are bool, int, string and error.
// Variable definition with default value.
var a int
var a, b int
// Variable definition with assigned value.
var a int = 5
var a, b int = divisionWithRemainder(5, 2)
// Variable definition short form.
a := 5
a, b := 5, 6
a, b := divisionWithRemainder(5, 2)
Control flow
// If-statement.
if a < 5 {
// Do something.
} else if > 5 {
// Do something.
} else {
// Do something else.
}
// Switch-statement.
switch a {
case 5:
// Do something.
case 6:
// Do something.
default:
// Do something else.
}
switch true {
case a == 5:
// Do something.
default:
// Do something else.
}
switch {
case false:
// Do something.
default:
// Do something else.
}
// For-loop.
for {
// Do something.
}
for a == 5 {
// Do something.
}
for i := 0; i < 5; i++ {
// Do something.
}
// For-range-loop (supported for slices and strings).
for i, v := range s {
// Do something.
}
Functions
// Function definition.
func division(a int, b int) int {
return a / b
}
func divisionWithRemainder(a int, b int) (int, int) {
return division(a, b), a % b
}
// Function call.
sum(2, 5)
Slices
// Slice creation.
s := []int{}
// Slice creation with values.
s := []int{1, 2, 3}
// Slice assignment.
s[0] = 10
// Slice evaluation.
v := s[0]
// Slice length.
l := len(s)
// Slice iteration.
for i := 0; i < len(s); i++ {
v := s[i]
}
Programs/Scripts
// Programs/Scripts are called by stating the name preceded by an @.
@dir("/b")
// Similar to Bash/Batch, the output can be piped into another program/script.
@dir("/b") | @sort("/r")
// To capture the output, just assign the call chain to variables.
stdout, stderr, code := @dir("/b") | @sort("/r")
// To specify the path to a program/script, a string literal is used.
@`helper\dir.bat`("/b") // Equivalent to @"helper\\dir.bat"("/b")
Imports
TypeShell does not support import of packages like Go does, but it supports single file imports. If an imported script is not a standard "library" script, an alias needs to be defined.
// Relative file import.
import (
hp "helper.tsh"
)
hp.HelperFunc()
// Standard "library" import.
import (
"strings"
)
print(strings.Contains("Hello World", "World")) // Prints 1.
Builtin
// Returns the length of a slice or a string.
len(slice)
len(str)
// Prints the passed arguments to stdout.
print(arg0, arg1, ...)
// Asks for user input.
input()
input(promptString)
// Copies values from srcSlice to dstSlice. Returns the copied length.
copy(dstSlice, srcSlice)
// Reads file content.
read(path)
// Writes file content.
write(path, contentString)
write(path, contentString, appendBool)
// Checks if a path exists.
exists(path)
// Converts an integer to a string.
itoa(str)
// Kills the program with an error.
panic(err)
Caveats
Condition evaluation
In contrast to many other programming languages, TypeShell evaluates all conditions before the actual statement. This is done to handle the limitations of Batch/Bash. HINT: This is also true for switch-evaluations since switchs are internally converted to ifs.
if a == 1 && b == 1 {
// Do something.
}
// How it's handled internally.
h1 := a == 1
h2 := b == 2
h3 := a && b
if h3 {
// Do something.
}
Error and nil
In TypeShell error is just a string type and nil is an empty string. However, they are still supported to provide developers with the possibility to use the typical Go workflow of error checking.
err := func()
if err != nil {
// Do something.
}
Functions
- Functions must be defined before being used.
- Recursions are not supported yet.
Slices
If a slice index does not exist on assignment, it and its intermediate indices are created.
s := []string{"Hello"}
s[2] = "World"
print(s[0]) // Prints "Hello".
print(s[1]) // Prints "".
print(s[2]) // Prints "World".
Visual Studio Code
There is no extension for VSCode yet. However, since the code is very Go-like, adding the ".tsh" extension to the settings should serve as a first workaround.
- Open VSCode.
- Go to File -> Preferences -> Settings.
- Seach for "file associations".
- Add "*.tsh" to the list and associate it with Go.